生成函数的一般应用;

#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
*/

 

posted on 2018-01-27 17:56  湮灭之瞳  阅读(112)  评论(0编辑  收藏  举报