zoukankan      html  css  js  c++  java
  • hdu6801.Game on a Circle

    题目大意

    n个石子围成一圈,从第一个开始顺时针考虑,每次有p的概率取走当前石子,问c号石子是第1...n个被取走的概率

    n<=1e6

    题解

    记q=1-p,枚举石子c被取走之前的完整轮数t,设x^i表示是第i+1个被取走的概率

    (sum_{t=0}^{infty} q^tp(q^{t+1}+(1-q^{t+1})x)^{c-1}(q^{t}+(1-q^{t})x)^{n-c})

    其中1-q^t实际上是考虑可以取已经取走的石子,并且最后概率加起来不变且只记一次,还可以统一考虑

    1-q^t不好搞,所以拆一下

    (=sum_{t=0}^{infty} q^tp(q^{t+1}(1-x)+x)^{c-1}(q^{t}(1-x)+x)^{n-c})

    (=psum_isum_jinom{c-1}{i}inom{n-c}{j}sum_{t=0}^{infty} q^{t+(t+1)i+tj}(1-x)^{i+j}x^{n-1-i-j})

    (=psum_isum_jinom{c-1}{i}inom{n-c}{j}q^i(1-x)^{i+j}x^{n-1-i-j}sum_{t=0}^{infty} q^{t(1+i+j)})

    (=psum_isum_jinom{c-1}{i}inom{n-c}{j}q^i(1-x)^{i+j}x^{n-1-i-j}frac{1}{1-q^{i+j+1}})

    (=psum_{k=0}^{n-1}sum_{i+j=k}inom{c-1}{i}inom{n-c}{j}q^i(1-x)^{k}x^{n-1-k}frac{1}{1-q^{k+1}})

    (f_k=sum_{i+j=k}inom{c-1}{i}inom{n-c}{j}q^i)

    (=psum_{k=0}^{n-1}f_k(1-x)^{k}x^{n-1-k}frac{1}{1-q^{k+1}})

    (=psum_{i=0}^{n-1}x^isum_{k=0}^{n-1}f_k(1-x)^{k}frac{1}{1-q^{k+1}}[x^{i+k+1-n}])

    (=psum_{i=0}^{n-1}x^isum_{k=0}^{n-1}f_k inom{k}{n-i-1}(-1)^{i+k+1-n}frac{1}{1-q^{k+1}})

    求出f之后就可以卷了

    f也可以卷,但是1e6很悬

    (f_k=sum_{i+j=k}inom{c-1}{i}inom{n-c}{j}q^i)

    (F(x)=sum_i x^if_i),则(F(x)=(1+qx)^{c-1}(1+x)^{n-c})

    考虑推出f的递推式,有显然的sb推法:


    ((1+qx)^{c-1}=sum inom{c-1}{i}q^ix^i)

    (((1+qx)^{c-1})'=sum inom{c-1}{i}q^iix^{i-1}=sum inom{c-2}{i-1}(c-1)q^ix^{i-1}=(c-1)qsum inom{c-2}{i-1}q^{i-1}x^{i-1})

    (=(c-1)q(1+qx)^{c-2})

    (F(x)=(1+qx)^{c-1}(1+x)^{n-c})

    (((1+qx)^{c-1})'(1+x)^{n-c}=(c-1)q(1+qx)^{c-2}(1+x)^{n-c}=(c-1)qfrac{F(x)}{1+qx})

    ((1+x)^{n-c})同理

    然后在群里被教育了一顿


    正常推法:

    (ln F(x)=frac{F'(x)}{F(x)}=(ln (1+qx)^{c-1}(1+x)^{n-c})')

    (=((c-1)ln (1+qx)+(n-c)ln (1+x))')

    注意其中的ln(1+x)和ln(1+qx)是复合函数求导,(1+qx)'=q

    (=frac{(c-1)q}{1+qx}+frac{n-c}{1+x})

    所以(F'(x)=frac{(c-1)qF(x)}{1+qx}+frac{(n-c)F(x)}{1+x})

    ([x^i]F(x)=(i+1)f_{i+1}),根据x^i的系数可以列出等式:

    (q(i-1)f_{i-1}+(q+1)if_i+(i+1)f_{i+1}=((c-1)q+n-c)f_i+((c-1)q+(n-c)q)f_{i-1})

    整理可得

    (f_{i+1}=frac{1}{i+1}(((c-1)q+n-c-(q+1)i)f_i+((c-1)q+(n-c)q-q(i-1))f_{i-1}))

    (f_{i+1}=frac{1}{i+1}(((c-1)q+n-c-(q+1)i)f_i+q(n-i)f_{i-1}))

    完结撒花

    code

    #include <bits/stdc++.h>
    #define fo(a,b,c) for (a=b; a<=c; a++)
    #define fd(a,b,c) for (a=b; a>=c; a--)
    #define mod 998244353
    #define Mod 998244351
    #define ll long long
    #define G 3
    //#define file
    using namespace std;
    
    ll a[2097152],b[2097152],f[2097152],jc[1000001],Jc[1000001],w[1000001],p,q,T,ans,N2;
    int N,len,n,i,j,k,l,A,B,c;
    
    ll qpower(ll a,int b) {ll ans=1; while (b) {if (b&1) ans=ans*a%mod;a=a*a%mod;b>>=1;} return ans;}
    void dft(ll *a,int tp)
    {
    	static ll A[2097152];
    	int i,j,k,l,S=N,s1=2,s2=1;
    	ll u,v,w,W;
    	
    	fo(i,0,N-1)
    	{
    		j=i,k=0;
    		fo(l,1,len)
    		k=k*2+(j&1),j>>=1;
    		A[i]=a[k];
    	}
    	memcpy(a,A,N*8);
    	
    	fo(i,1,len)
    	{
    		w=(tp==1)?qpower(G,(mod-1)/s1):qpower(G,(mod-1)-(mod-1)/s1);S>>=1;
    		fo(j,0,S-1)
    		{
    			W=1;
    			fo(k,0,s2-1)
    			{
    				u=a[j*s1+k],v=a[j*s1+k+s2]*W%mod;
    				a[j*s1+k]=(u+v)%mod;
    				a[j*s1+k+s2]=(u-v)%mod;
    				W=W*w%mod;
    			}
    		}
    		s1<<=1,s2<<=1;
    	}
    }
    ll C(int n,int m) {if (n<m) return 0;return jc[n]*Jc[m]%mod*Jc[n-m]%mod;}
    void init()
    {
    	int i,j,k,l;
    	f[0]=1;f[1]=(C(c-1,1)*q+C(n-c,1))%mod;
    	fo(i,2,n-1) f[i]=((q*(c-1)+n-c-(q+1)*(i-1))%mod*f[i-1]+(q*(n-(i-1)))%mod*f[i-2])%mod*w[i]%mod;
    }
    
    int main()
    {
    	#ifdef file
    	freopen("hdu6801.in","r",stdin);
    	#endif
    	
    	jc[0]=jc[1]=Jc[0]=Jc[1]=w[1]=1;
    	fo(i,2,1000000) w[i]=mod-w[mod%i]*(mod/i)%mod,jc[i]=jc[i-1]*i%mod,Jc[i]=Jc[i-1]*w[i]%mod;
    	
    	scanf("%d",&T);
    	for (;T;--T)
    	{
    		scanf("%d%d%d%d",&n,&A,&B,&c);len=ceil(log2(n))+1;N=qpower(2,len);N2=qpower(N,Mod);
    		p=1ll*A*qpower(B,Mod)%mod,q=1-p;
    		memset(f,0,N*8);
    		memset(a,0,N*8);
    		memset(b,0,N*8);
    		init();
    		
    		fo(i,0,n-1) a[i]=qpower(1-qpower(q,i+1),Mod)*f[i]%mod*jc[i]%mod*(((i+1-n)&1)?-1:1);
    		fo(i,n-1,2*(n-1)) b[(n-1)*2-i]=Jc[i-(n-1)];
    		dft(a,1),dft(b,1);
    		fo(i,0,N-1) a[i]=a[i]*b[i]%mod;
    		dft(a,-1);
    		fo(i,0,n-1) printf("%lld
    ",(a[2*(n-1)-i]*N2%mod*((i&1)?-1:1)+mod)%mod*p%mod*Jc[n-1-i]%mod);
    	}
    	
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    学习:类和对象——继承
    学习:类和对象——运算符重载
    域权限维持:Skeleton Key
    域权限维持:SSP密码记录
    学习:类和对象——友元
    学习:类和对象——对象模型和this指针
    学习:类和对象——静态成员变量和函数
    学习:类和对象——初始化列表和内部类
    学习:类和对象——深拷贝和浅拷贝
    二维数组中的查找
  • 原文地址:https://www.cnblogs.com/gmh77/p/13410945.html
Copyright © 2011-2022 走看看