【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 }
View Code

 

posted @ 2015-07-24 16:03  mithrilhan  阅读(199)  评论(0编辑  收藏  举报