Description
因为小Y 是知名的白富美,所以自然也有很多的追求者,这一天这些追求者打算进行一次游戏来踢出一些人,小R 自然也参加了。
这个游戏有n 个人参加,每一轮随机选出一个还没有出局的人x,接着x 会出局。x 在出局之后剩下的人会受到一次攻击,每一个人在遭到攻击之后会有p 的概率出局。(注意遭到攻击出局的人是不能攻击剩下的人的)
在所有人都出局之后,遭受攻击次数等于特定值的人能够成为胜者。所以现在小R 想要知道对于每一个0 <= k < n,自己恰好在遭受k 次攻击之后出局的概率是多少。(这里的出局指的不是被攻击出局)
注意在这题中,所有数值的运算在模258280327 的意义下进行。
对于每组数据,输出一行n 个整数,表示对于k = 0到n - 1 的概率在模258280327 意义下的值。
对于60% 的数据,n <=100
对于100% 的数据,n <= 2* 103,1 <= T <= 5,0<= x < y <= 109
Solution
感觉和猎人杀那题很像啊
我们设f[i,j]表示小R玩到第i轮剩下j个人的概率,枚举k表示这一轮因被攻击而出局了多少人,这样转移是n^3的
考虑钦定一个被选的顺序,设f[i,j]表示选到了第i个人,剩余的人被攻击了j次的概率。讨论当前这个人,如果仍然活着那么就选他淘汰并攻击剩余的人,否则就略过不选。可以发现除了小R外所有人都是等价的,因此我们这样钦定顺序不会影响答案
Code
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
typedef long long LL;
const int MOD=258280327;
const int N=2005;
LL f[N][N],wjp[N];
int read() {
int x=0,v=1; char ch=getchar();
for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):(v),ch=getchar());
for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar());
return x*v;
}
LL ksm(LL x,LL dep) {
LL res=1;
for (;dep;dep>>=1) {
(dep&1)?(res=res*x%MOD):0;
x=x*x%MOD;
}
return res;
}
void upd(LL &x,LL y) {
x+=y; (x>=MOD)?(x-=MOD):0;
}
int main(void) {
for (int T=read();T--;) {
int n=read(),x=read(),y=read();
LL p=(x%MOD)*(ksm(y%MOD,MOD-2))%MOD;
rep(i,0,n) wjp[i]=ksm(1-p+MOD,i);
f[0][0]=1;
rep(i,1,n) rep(j,1,i) {
f[i][j]=0;
upd(f[i][j],f[i-1][j-1]*wjp[j-1]%MOD);
upd(f[i][j],f[i-1][j]*(1+MOD-wjp[j])%MOD);
}
LL ny=ksm(n,MOD-2);
rep(k,0,n-1) {
LL ans=0;
rep(i,0,n-1) upd(ans,f[i][k]*wjp[k]%MOD);
printf("%lld ", ans*ny%MOD);
} puts("");
}
return 0;
}