zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    Problem S: 分数类的模板数组类
    Problem E: 向量的运算
    Problem D: 强悍的矩阵运算来了
    Problem C: Person类与Student类的关系
    Problem B: 还会用继承吗?
    Problem A: 求个最大值
    Problem B: 数组类(II)
    树的直径题集
    LCA题集
    线段树总结
  • 原文地址:https://www.cnblogs.com/xiepingfu/p/7454333.html
Copyright © 2011-2022 走看看