Description
Solution
T1 game
咕咕咕
T2 string
咕咕咕
T3 hunter
概率dp
\(f_{i,j}\)表示得是当前被射中的是第\(i\)号猎人,当前还有\(j\)个人时,的答案。
当然我们所说的\(i\)号是对当前剩余猎人进行排序后,从\(1\)号猎人开始数的第\(i\)个,所以\(i\leq j\)
有一个约定是当前剩下的人中一定有\(1\),不然答案就是\(0\)了,我们根本不需要计算
于是:
\[ f_{i,j}=\frac{1}{2}(f_{Nex(i),j,},f_{nex(i),j-1}) \]
自行意会,这里的\(Nex(i)\)和\(nex(i)\)不是同一个,因为当人数减少后,对应编号会变。我们设\(t_{i,j}=f_{nex(i),j-1}\),注意\(t_{1,j}=0\),要特别计算
但是,计算\(f_{i,j}\),要求的值形成了若干个环
小学数学告诉我们:
- 环的数量是\(gcd(j,k)\)
- 环的长度是\(\frac{j}{gcd(j,k)}\)
我们对每个环进行计算,设这个环上的元素一次是\(a_{p_1},a_{p_2},...,a_{p_n}\)
于是就有
\[ a_{p_i}=\frac{1}{2}(t_{P_i}+a_{p_i}) \]
暴力解方程可以得知:
\[ a_1=\frac{2^{n-1}t_1+2^{n-2}t_2+...+t_n}{2^n-1} \]
其他的就是轮换一下,就不说啦然后,就没有然后了
#include<bits/stdc++.h>
#define ll long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
const int mod=1e9+7,MN=2005;
int n,k;
int fpow(int x,int m){int r=1;for(;m;m>>=1,x=1ll*x*x%mod)if(m&1)r=1ll*r*x%mod;return r;}
int gcd(int x,int y){return x?gcd(y%x,x):y;}
int f[MN][MN],t[MN],p2[MN];
signed main()
{
register int i,j,h,ln;
n=read();k=read();
f[1][1]=1;
for(p2[0]=i=1;i<=n+1;++i) p2[i]=p2[i-1]*2ll%mod;
for(i=2;i<=n;++i)
{
#define nx(x) ((x+k%i-1)%i+1)
for(j=1;j<=i;++j)
{
int nex=((k-1)%(i-1)+1+j-1-1)%(i-1)+1;
t[j]=f[nex][i-1];
}
t[1]=0;
int num=gcd(i,k%i),len=i/num,val,Inv=fpow(p2[len]-1,mod-2);
for(j=1;j<=num;++j)
{
val=0;
for(ln=len,h=j;ln;--ln,h=nx(h)) (val+=1ll*p2[ln-1]*t[h]%mod)%=mod;
f[j][i]=1ll*val*Inv%mod;
for(ln=len,h=j;ln>1;--ln,h=nx(h))
{
(val+=mod-1ll*p2[len-1]*t[h]%mod)%=mod,val=2ll*val%mod,(val+=t[h])%=mod;
f[nx(h)][i]=1ll*val*Inv%mod;
}
}
}
printf("%d\n",f[(k-1)%n+1][n]);
return 0;
}
Blog来自PaperCloud,未经允许,请勿转载,TKS!