【FFT】 UVA 12298 Super Poker II
通道:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=84075#problem/C
题意:
就是现在有一堆扑克里面的牌有无数张, 每种合数的牌有4中不同花色各一张(0, 1都不是合数), 没有质数或者大小是0或者1的牌
现在这堆牌中缺失了其中的 c 张牌, 告诉你a, b, c接下来c张不同的丢失的牌, 然后求从这堆牌中拿出各种花色的牌各一张, 得到的点数和是k的种数有多少种(一种组合算作一种), 需要全部所有的a <= k <= b的k对应的结果
代码:
1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 #include <algorithm> 5 6 using namespace std; 7 8 typedef long long ll; 9 10 const int MAX_N = 100007; 11 const int MAX_M = 100007; 12 const long double PI = acos(-1.0); 13 14 struct Complex { 15 long double r, i; 16 Complex(long double _r, long double _i) { 17 r = _r; 18 i = _i; 19 } 20 Complex operator + (const Complex &c) { 21 return Complex(c.r + r, c.i + i); 22 } 23 Complex operator - (const Complex &c) { 24 return Complex(r - c.r, i - c.i); 25 } 26 Complex operator * (const Complex &c) { 27 return Complex(c.r * r - c.i * i, c.r * i + c.i * r); 28 } 29 Complex operator / (const int &c) { 30 return Complex(r / c, i / c); 31 } 32 Complex(){} 33 }; 34 namespace FFT { 35 int rev(int id, int len) { 36 int ret = 0; 37 for(int i = 0; (1 << i) < len; ++i) { 38 ret <<= 1; 39 if(id & (1 << i)) ret |= 1; 40 } 41 return ret; 42 } 43 Complex A[MAX_M << 3]; 44 void FFT(Complex *a, int len, int DFT) { 45 for(int i = 0; i < len; ++i) A[rev(i, len)] = a[i]; 46 for(int s = 1; (1 << s) <= len; ++s) { 47 int m = (1 << s); 48 Complex wm = Complex(cos(PI * DFT * 2 / m), sin(PI * DFT * 2 / m)); 49 for(int k = 0; k < len; k += m) { 50 Complex w = Complex(1, 0); 51 for(int j = 0; j < (m >> 1); j++) { 52 Complex t = w * A[k + j + (m >> 1)]; 53 Complex u = A[k + j]; 54 A[k + j] = u + t; 55 A[k + j + (m >> 1)] = u - t; 56 w = w * wm; 57 } 58 } 59 } 60 if(DFT == -1) for(int i = 0; i < len; ++i) A[i] = A[i] / len; 61 for(int i = 0; i < len; i++) a[i] = A[i]; 62 } 63 }; 64 65 Complex S[MAX_M << 3], H[MAX_M << 3], C[MAX_M << 3], D[MAX_M << 3]; 66 bool prime[MAX_N >> 1]; 67 68 void init() { 69 memset(prime, 1, sizeof prime); 70 int limit = MAX_N >> 1; 71 for (int i = 2; i < limit; ++i) { 72 if (prime[i]) { 73 for (int j = 2 * i; j < limit; j += i) 74 prime[j] = false; 75 } 76 } 77 } 78 79 int main() { 80 init(); 81 int a, b, c; 82 while (3 == scanf("%d%d%d", &a, &b, &c)) { 83 if (0 == a && 0 == b && 0 == c) break; 84 for (int i = 0; i <= b; ++i) if (!prime[i]) 85 S[i] = H[i] = C[i] = D[i] = Complex(1, 0); 86 else S[i] = H[i] = C[i] = D[i] = Complex(0, 0); 87 ++b; 88 int len = 1; 89 while (len < b) len <<= 1; len <<= 3; 90 for (int i = b; i < len; ++i) S[i] = H[i] = C[i] = D[i] = Complex(0, 0); 91 for(int i = 0; i < c; i++) { 92 int v; 93 char type; 94 scanf("%d%c", &v, &type); 95 switch(type) { 96 case 'S': S[v] = Complex(0, 0); break; 97 case 'H': H[v] = Complex(0, 0); break; 98 case 'C': C[v] = Complex(0, 0); break; 99 case 'D': D[v] = Complex(0, 0); break; 100 } 101 } 102 FFT::FFT(S, len, 1); FFT::FFT(H, len, 1); FFT::FFT(C, len, 1); FFT::FFT(D, len, 1); 103 for (int i = 0; i < len; ++i) S[i] = S[i] * H[i] * C[i] * D[i]; 104 FFT::FFT(S, len, -1); 105 for (int i = a; i < b; ++i) printf("%lld\n", (ll)(S[i].r + 0.5)); puts(""); 106 } 107 return 0; 108 }