jzoj4212 我想大声告诉你

11 篇文章 0 订阅

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值