zoukankan      html  css  js  c++  java
  • 洛谷P3784 [SDOI2017]遗忘的集合(生成函数)

    题面

    传送门

    题解

    生成函数这厮到底还有什么是办不到的……

    首先对于一个数(i),如果存在的话可以取无限多次,那么它的生成函数为

    [sum_{j=0}^{infty}x^{ij}={1over 1-x^i} ]

    然后我们设(a_iin [0,1])表示这个数是否存在这个集合里,那么给出了(F),满足

    [F(x)=prod_{i=1}^nleft({1over 1-x^i} ight)^{a_i} ]

    然后我们现在就是要求出(a_i)

    首先我们要知道一个东西

    [ln(1-x^i)=-sum_{j=1}^{infty}frac{x^{ij}}{j} ]

    证明抄(Cyhlnj)

    [ln F(x)=G(x)\frac{F'(x)}{F(x)}=G'(x)\frac{-ix^{i-1}}{1-x^i}=G'(x)\-sum_{j=0}^{infty} ix^{i-1+ij}=G'(x)\-sum_{j=0}^{infty}frac{ix^{i+ij}}{i+ij}=G(x)\-sum_{j=1}^{infty}frac{x^{ij}}{j}=G(x) ]

    我们先对原来的式子两边取(ln),再用上面的式子代入

    [egin{align} -ln F(x) &=sum_{i=1}^n a_iln (1-x^i)\ &=-sum_{i=1}^n a_isum_{j=1}^{infty}frac{x^{ij}}{j}\ end{align} ]

    然后我们枚举(d=ij),有

    [ln F(x)=sum_{d=1}^{infty} x^dsum_{imid d}a_i{iover d} ]

    然后我们现在就求出了(sum_{imid d}a_i{iover d}),这个我们直接枚举倍数,然后让每一个数的倍数减去它的贡献就行了

    最后一个问题是,这里的模数不一定有原根,所以得拆系数

    //minamoto
    #include<bits/stdc++.h>
    #define R register
    #define ll long long
    #define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
    #define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    using namespace std;
    char buf[1<<21],*p1=buf,*p2=buf;
    inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
    int read(){
        R int res,f=1;R char ch;
        while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
        for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
        return res*f;
    }
    char sr[1<<21],z[20];int K=-1,Z=0;
    inline void Ot(){fwrite(sr,1,K+1,stdout),K=-1;}
    void print(R int x){
        if(K>1<<20)Ot();if(x<0)sr[++K]='-',x=-x;
        while(z[++Z]=x%10+48,x/=10);
        while(sr[++K]=z[Z],--Z);sr[++K]=' ';
    }
    const int N=6e5+5;const double Pi=acos(-1.0);
    int P;
    inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
    inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
    inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
    int ksm(R int x,R int y){
    	R int res=1;
    	for(;y;y>>=1,x=mul(x,x))if(y&1)res=mul(res,x);
    	return res;
    }
    struct cp{
    	double x,y;
    	cp(R double xx=0,R double yy=0){x=xx,y=yy;}
    	inline cp operator +(const cp &b)const{return cp(x+b.x,y+b.y);}
    	inline cp operator -(const cp &b)const{return cp(x-b.x,y-b.y);}
    	inline cp operator *(const cp &b)const{return cp(x*b.x-y*b.y,x*b.y+y*b.x);}
    	inline cp operator *(const double &b)const{return cp(x*b,y*b);}
    }O[N];
    int r[N],c[N],d[N],e[N],f[N],g[N],h[N],n,len,ans;
    void FFT(cp *A,int ty,int lim){
    	fp(i,0,lim-1)if(i<r[i])swap(A[i],A[r[i]]);
    	for(R int mid=1;mid<lim;mid<<=1)
    		for(R int j=0;j<lim;j+=(mid<<1))
    			for(R int k=0;k<mid;++k){
    				cp x=A[j+k],y=O[mid+k]*A[j+k+mid];
    				A[j+k]=x+y,A[j+k+mid]=x-y;
    			}
    	if(ty==-1){
    		reverse(A+1,A+lim);
    		double k=1.0/lim;fp(i,0,lim-1)A[i]=A[i]*k;
    	}
    }
    void Mul(int *a,int *b,int *c,int len){
    	static cp A[N],B[N],C[N],D[N],F[N],G[N],H[N];
    	int l=0,lim=1;while(lim<(len<<1))lim<<=1,++l;
    	fp(i,0,lim-1)r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
    	for(R int i=1;i<lim;i<<=1)fp(k,0,i-1)O[i+k]=cp(cos(Pi*k/i),sin(Pi*k/i));
    	fp(i,0,len-1){
    		A[i].x=a[i]>>15,B[i].x=a[i]&32767;
    		C[i].x=b[i]>>15,D[i].x=b[i]&32767;
    		A[i].y=B[i].y=C[i].y=D[i].y=0;
    	}fp(i,len,lim-1)A[i]=B[i]=C[i]=D[i]=0;
    	FFT(A,1,lim),FFT(B,1,lim),FFT(C,1,lim),FFT(D,1,lim);
    	fp(i,0,lim-1)
    		F[i]=A[i]*C[i],G[i]=A[i]*D[i]+B[i]*C[i],H[i]=B[i]*D[i];
    	FFT(F,-1,lim),FFT(G,-1,lim),FFT(H,-1,lim);
    	fp(i,0,len-1)c[i]=(((ll)(F[i].x+0.5)%P<<30)+((ll)(G[i].x+0.5)<<15)+((ll)(H[i].x+0.5)))%P;
    	fp(i,len,lim-1)c[i]=0;
    }
    void Inv(int *a,int *b,int len){
    	if(len==1)return b[0]=ksm(a[0],P-2),void();
    	Inv(a,b,len>>1);
    	Mul(a,b,c,len),Mul(c,b,d,len);
    	fp(i,0,len-1)b[i]=dec(add(b[i],b[i]),d[i]);
    }
    void Ln(int *a,int *b,int len){
    	fp(i,1,len-1)e[i-1]=mul(a[i],i);
    	Inv(a,f,len),Mul(e,f,b,len);
    	fd(i,len-1,1)b[i]=mul(b[i-1],ksm(i,P-2));
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    	n=read(),P=read();
    	int len=1;while(len<=n)len<<=1;
    	fp(i,1,n)g[i]=read();
    	g[0]=1,Ln(g,h,len);
    	fp(i,1,n)h[i]=mul(i,h[i]);
    	fp(i,1,n)for(R int j=i+i;j<=n;j+=i)h[j]=dec(h[j],h[i]);
    	fp(i,1,n)if(h[i])++ans;
    	print(ans),sr[K]='
    ';
    	fp(i,1,n)if(h[i])print(i);
    	return Ot(),0;
    }
    
  • 相关阅读:
    题解 CF171G 【Mysterious numbers
    题解 P1157 【组合的输出】
    题解 P3955 【图书管理员】
    题解 P2036 【Perket】
    题解 CF837A 【Text Volume】
    题解 CF791A 【Bear and Big Brother】
    题解 CF747A 【Display Size】
    题解 P1332 【血色先锋队】
    题解 P2660 【zzc 种田】
    题解 P4470 【[BJWC2018]售票】
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/10439234.html
Copyright © 2011-2022 走看看