生成函数的一般应用;
#include<iostream> #include<cstring> #include<cmath> #include<cstdio> #include<algorithm> using namespace std; const int maxn=250000; const long double PI=acos(-1.0); struct cp{ long double r,i; cp(long double _r=0,long double _i=0):r(_r),i(_i){} cp operator+(const cp&a){ return cp(r+a.r,i+a.i); } cp operator-(const cp&a){ return cp(r-a.r,i-a.i); } cp operator*(const cp&a){ return cp(r*a.r-i*a.i,r*a.i+a.r*i); } void pu(long double _r=0,long double _i=0){ r=_r;i=_i; } }wn,w,A[4][maxn],tmp[maxn],x,y; int n,dig[maxn],rev[maxn],L; void fft(cp a[],int flag){ for(int i=0;i<n;++i)tmp[i]=a[rev[i]]; for(int i=0;i<n;++i)a[i]=tmp[i]; for(int i=2;i<=n;i<<=1){ cp wn(cos(2*PI/i),flag*sin(2*PI/i)); for(int k=0;k<n;k+=i){ cp w(1,0); for(int j=k;j<k+i/2;++j){ x=a[j];y=a[j+i/2]*w; a[j]=x+y;a[j+i/2]=x-y; w=w*wn; } } } if(flag==-1)for(int i=0;i<n;++i)a[i].r/=n; } void solve(cp aa[],cp bb[],int len){ memset(rev,0,sizeof(rev)); memset(dig,0,sizeof(dig)); for(n=1,L=0;n<(len<<1);n<<=1,++L); for(int i=0;i<n;++i){ int ll=0; for(int t=i;t;t>>=1)dig[ll++]=t&1; for(int j=0;j<L;++j)rev[i]=(rev[i]<<1)|dig[j]; } for(int i=len;i<n;++i)aa[i].pu(0),bb[i].pu(0); //for(int i=0;i<n;++i)cout<<aa[i].r<<' ';cout<<endl; fft(aa,1);fft(bb,1); for(int i=0;i<n;++i)aa[i]=aa[i]*bb[i]; fft(aa,-1); } bool is[50005],ex[4][50005]; char ss[5]; int main(){ for(long long i=2;i<50005;++i){ if(!is[i]){ for(long long j=i+i;j<50005;j+=i)is[j]=1; } } int a,b,c,op; while(scanf("%d%d%d",&a,&b,&c)==3&&(a||b||c)){ memset(ex,1,sizeof(ex)); for(int i=1;i<=c;++i){ scanf("%d",&op);scanf("%s",ss); if(ss[0]=='S')ex[0][op]=0; else if(ss[0]=='H')ex[1][op]=0; else if(ss[0]=='C')ex[2][op]=0; else ex[3][op]=0; } for(int i=0;i<4;++i) for(int j=0;j<b;++j){ if(is[j]&&ex[i][j]){ A[i][j].pu(1); } else A[i][j].pu(0); } solve(A[0],A[1],b); solve(A[2],A[3],b); solve(A[0],A[2],b); for(int i=a;i<=b;++i){ printf("%lld\n",(long long)(A[0][i].r+0.5)); } cout<<endl; } //system("pause"); return 0; } /* 12 20 2 4S 6H 0 0 0 */