本文共 2932 字,大约阅读时间需要 9 分钟。
因为小 Y 是知名的白富美,所以自然也有很多的追求者,这一天这些追求者打算进行一次游戏来踢出一些人,小 R 自然也参加了。
这个游戏有 n n n 个人参加,每一轮随机选出一个还没有出局的人 x x x ,接着 x x x 会出局。 x x x 在出局之后剩下的人会受到一次攻击,每一个人在遭到攻击之后会有 p p p 的概率出局。(注意遭到攻击出局的人是不能攻击剩下的人的) 在所有人都出局之后,遭受攻击次数等于特定值的人能够成为胜者。所以现在小 R 想要知道对于每一个 0 < = k < n 0 <= k < n 0<=k<n ,自己恰好在遭受 k k k 次攻击之后出局的概率是多少。(这里的出局指的不是被攻击出局) 注意在这题中,所有数值的运算在模 258280327 258280327 258280327 的意义下进行。第一行输入一个正整数 T T T 表示数据组数。
对于每一组数据输入仅一行三个数 n , x , y n, x, y n,x,y ,表示在这组数据中有 n n n 个人参赛, p = x / y p = x/y p=x/y 。保证 y y y 和 258280327 258280327 258280327 互质。对于每组数据,输出一行 n n n 个整数,表示对于 k = 0 k = 0 k=0 到 n − 1 n - 1 n−1 的概率在模 258280327 258280327 258280327 意义下的值。
23 40 1009 32 1049
172186885 92980918 16529941229582513 163885050 39458156 102374877 116777758 216371874 55544199 95860736 8136787
对于 60 % 60\% 60% 的数据, n < = 100 n <=100 n<=100
对于 100 % 100\% 100% 的数据, n < = 2 ∗ 1 0 3 , 1 < = T < = 5 , 0 < = x < y < = 1 0 9 n <= 2* 10^3,1 <= T <= 5,0<= x < y <= 10^9 n<=2∗103,1<=T<=5,0<=x<y<=109这道题是一道概率 dp 。
我们可以发现,其实这个人出局的概率和其他人毫无关系,那我们就默认其他人是从 1 1 1 号开始轮流被选的。然后我们就设 f [ i ] [ j ] f[i][j] f[i][j] 为在第 i i i 次挂掉,而且承受了 j j j 次攻击的概率。
(记得这里是包括被打出去)那我们有两种情况,一种是被打出去,一种是被选中。那就是 f [ i ] [ j ] = f [ i − 1 ] [ j − 1 ] ∗ ( 1 − p ) j − 1 + f [ i − 1 ] [ j ] ∗ ( 1 − ( 1 − p ) j ) f[i][j] = f[i - 1][j - 1] * (1-p)^{j-1} + f[i - 1][j] * (1-(1-p)^j) f[i][j]=f[i−1][j−1]∗(1−p)j−1+f[i−1][j]∗(1−(1−p)j) 。
至于初始化,就是 f [ 0 ] [ 0 ] = 1 f[0][0] = 1 f[0][0]=1 。但是 f [ i ] [ j ] f[i][j] f[i][j] 包括了被打出去的,但是题目不要被打出去的,那我们就还要求 a n s ans ans 。
那每一个 k k k (我这里用了 j j j )其实就是 1 / n ∗ ∑ i = 0 n − 1 f [ i ] [ j ] ∗ ( 1 − p ) k 1/n*\sum_{i=0}^{n-1}f[i][j]*(1-p)^k 1/n∗∑i=0n−1f[i][j]∗(1−p)k 。p p p 和 1 / n 1/n 1/n 用逆元来求,然后 ( i − p ) x (i-p)^x (i−p)x 这种形式的就提前预处理出来(我这里用的是 m i [ x ] mi[x] mi[x] )。
还有就是记得要取模,最要要用 l o n g l o n g long\ long long long 。(因为我不知道不用行不行)#include#include #define ll long longusing namespace std;const ll mo = 258280327;int T;ll n, x, y, p, mi[2001];ll f[2001][2001], ans;ll ksm(ll x, ll y) { //快速幂 x %= mo; ll re = 1; for (; y; y >>= 1) { if (y & 1) re = re * x % mo; x = x * x % mo; } return re;}ll inv(ll now) { //除(逆元) return ksm(now, mo - 2);}int main() { scanf("%d", &T);//读入 for (int times = 1; times <= T; times++) { memset(mi, 0, sizeof(mi));//初始化 memset(f, 0, sizeof(f)); scanf("%lld %lld %lld", &n, &x, &y);//读入 p = x * inv(y) % mo;//求出p mi[0] = 1;//初始化 for (int i = 1; i <= n; i++) mi[i] = (mi[i - 1] * (1 - p + mo) % mo) % mo;//预处理(1-p)^i f[0][0] = 1;//初始化 for (int i = 1; i <= n; i++) for (int j = 1; j <= i; j++) f[i][j] = ((f[i - 1][j - 1] * mi[j - 1]) % mo + (f[i - 1][j] * ((1 - mi[j] + mo) % mo)) % mo) % mo;//求出f for (int j = 0; j < n; j++) { ans = 0; for (int i = 0; i < n; i++) ans = (ans + (f[i][j] * mi[j]) % mo) % mo;//求出答案 printf("%lld ", (ans * inv(n)) % mo);//输出 } printf("\n"); } return 0;}
转载地址:http://hgph.baihongyu.com/