题解
- 题目大意:n个人包括主人公小R,每轮会随机等概率的踢走一个人,而剩下的人每人会有x/y的概率被干掉,而被干掉的人不能攻击剩下的人,问小R在每轮出局的概率为多少
- 首先,我们可以知道这个问题至于小R小童鞋有关系,而剩下的n-1的小童鞋可以是等价的,也就是可以不用管它们
- 先想想部分分的做法,对于60%的数据,我们可以设f[i][j]为剩下i个人,被攻击了j轮的概率
- 那么就可以分成两种情况,一种是被钦定出局,一种是被干掉
- 对于第一种直接*1/i就好了,那么对于第二种情况,可以枚举一下这次攻击会有多少个人干出局,然后算概率就好了
- 再回来考虑一下100分做法:
- 因为我们知道其实其他的n-1的小童鞋是等价的,不如我们就钦定它是按顺序踢人走的
- 同样的设f[i][j]为剩下i个人,被攻击了j轮的概率
- 那么我们还是两种情况,一种就是正常出局,那么我们是很坚强的忍受了j-1轮的严刑拷打,f[i][j]=f[i-1][j-1]*(1-p)^(j-1)
- 另一种就是被打出去,那么我们就不能对剩下的人有任何的贡献,f[i][j]=f[i-1][j]*(1-(1-p)^j))
- 考虑一下答案究竟是啥子东东,那么可以知道对于每一轮剩下多少个人都是有可能的
- 这样的话,若j是固定,那就是

代码
1 #include <cstdio>
2 #include <cstring>
3 #define ll long long
4 using namespace std;
5 const ll N=200,mo=258280327;
6 int n,Q;
7 ll x,y,k,sum,ny[N],f[N][N],r,p;
8 ll ksm(ll a,ll b){ for (r=1;b;b>>=1,a=a*a%mo) if (b&1) r=r*a%mo; return r; }
9 int main()
10 {
11 scanf("%d",&Q);
12 while (Q--)
13 {
14 scanf("%d%lld%lld",&n,&x,&y),memset(f,0,sizeof(f)),f[1][0]=1,k=ksm(y,mo-2),p=ksm(n,mo-2),ny[0]=1;
15 for (int i=1;i<=n;i++) ny[i]=ny[i-1]*(y-x)%mo*k%mo;
16 for (int i=1;i<=n-1;i++)
17 for (int j=0;j<=n-1;j++)
18 if (f[i][j]) f[i+1][j+1]=(f[i+1][j+1]+f[i][j]*ny[j+1]%mo)%mo,f[i+1][j]=(f[i+1][j]+f[i][j]*(1-ny[j]+mo)%mo)%mo;
19 for (int j=0;j<=n-1;j++,sum=0)
20 {
21 for (int i=1;i<=n;i++) (sum+=f[i][j])%=mo;
22 printf("%lld ",sum*p%mo);
23 }
24 printf("
");
25 }
26 }