UVA 12298 Super Poker II (FFT)

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;

const int N = 1000005;
const long double pi = acos(-1.0);

struct Complex
{
    long double r,i;
    Complex(long double r=0, long double i=0):r(r),i(i) {};
    Complex operator+(const Complex &rhs)
    {
        return Complex(r + rhs.r,i + rhs.i);
    }
    Complex operator-(const Complex &rhs)
    {
        return Complex(r - rhs.r,i - rhs.i);
    }
    Complex operator*(const Complex &rhs)
    {
        return Complex(r*rhs.r - i*rhs.i,i*rhs.r + r*rhs.i);
    }
} pS[N], pH[N], pC[N], pD[N];
//len = 2^M,reverse F[i] with  F[j] j为i二进制反转
void rader(Complex F[],int len)
{
    int j = len >> 1;
    for(int i = 1; i < len - 1; ++i)
    {
        if(i < j) swap(F[i],F[j]);  // reverse
        int k = len>>1;
        while(j>=k)
        {
            j -= k;
            k >>= 1;
        }
        if(j < k) j += k;
    }
}

void FFT(Complex F[],int len,int t)
{
    rader(F,len);
    for(int h=2; h<=len; h<<=1)
    {
        Complex wn(cos(-t*2*pi/h),sin(-t*2*pi/h));
        for(int j=0; j<len; j+=h)
        {
            Complex E(1,0); //旋转因子
            for(int k=j; k<j+h/2; ++k)
            {
                Complex u = F[k];
                Complex v = E*F[k+h/2];
                F[k] = u+v;
                F[k+h/2] = u-v;
                E=E*wn;
            }
        }
    }
    if(t==-1)   //IDFT
        for(int i=0; i<len; ++i)
            F[i].r/=len;
}

void Conv(Complex a[],Complex b[],int len) //求卷积
{
    FFT(a,len,1);
    FFT(b,len,1);
    for(int i=0; i<len; ++i) a[i] = a[i]*b[i];
    FFT(a,len,-1);
}

long prime[N] = {0},num_prime = 0;
int isNotPrime[N] = {1, 1};
void init()
{
    for(long i = 2 ; i < N ; i ++)
    {
        if(! isNotPrime[i])
            prime[num_prime ++]=i;
        for(long j = 0 ; j < num_prime && i * prime[j] <  N ; j ++)
        {
            isNotPrime[i * prime[j]] = 1;
            if( !(i % prime[j] ) )
                break;
        }
    }
}



int main()
{
    int A, B, C;
    init();
    while(scanf("%d%d%d", &A, &B, &C) && (A+B+C))
    {
        memset(pS, 0, sizeof(pS));
        memset(pH, 0, sizeof(pH));
        memset(pC, 0, sizeof(pC));
        memset(pD, 0, sizeof(pD));
        for(int i=2; i<=B; ++i)
            if(isNotPrime[i])
                pS[i]=pH[i]=pC[i]=pD[i]=Complex(1);
        int len=1;
        while(len<B) len<<=1;
        len<<=3;
        while(C--)
        {
            int v;
            char type;
            scanf("%d%c", &v, &type);
            switch(type)
            {
                case 'S':pS[v]=Complex(0);break;
                case 'H':pH[v]=Complex(0);break;
                case 'C':pC[v]=Complex(0);break;
                case 'D':pD[v]=Complex(0);break;
            }
        }
        FFT(pS, len, 1), FFT(pH, len, 1), FFT(pC, len, 1), FFT(pD, len, 1);
        for(int i=0; i<len; ++i)
            pS[i]=pS[i]*pH[i]*pC[i]*pD[i];
        FFT(pS, len, -1);
        for(int i=A; i<=B; ++i)
            printf("%lld
", (long long)(pS[i].r+0.5));
        puts("");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/xiepingfu/p/7454333.html