1. 程式人生 > >UVA 12298 Super Poker II (FFT)

UVA 12298 Super Poker II (FFT)

otp ++ void lex const return 因子 dft per

#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\n", (long long)(pS[i].r+0.5)); puts(""); } return 0; }

UVA 12298 Super Poker II (FFT)