【FFT】 UVALIVE 6886 Golf Bot

通道:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4898

题意:就是现在给出N个数, 然后给出M个数询问这M书中有多少个可以是由这N个数中两个相加(同一个数可选两次)组成或者等于这N个数中的某一个

代码:

  1 #include<iostream>
  2 #include<sstream>
  3 #include<fstream>
  4 #include<vector>
  5 #include<list>
  6 #include<deque>
  7 #include<queue>
  8 #include<stack>
  9 #include<map>
 10 #include<set>
 11 #include<bitset>
 12 #include<algorithm>
 13 #include<cstdio>
 14 #include<cstdlib>
 15 #include<cstring>
 16 #include<cctype>
 17 #include<cmath>
 18 #include<ctime>
 19 #include<iomanip>
 20 using namespace std;
 21 const double eps(1e-8);
 22 typedef long long lint;
 23 
 24 const double PI = acos(-1.0);
 25 
 26 struct Complex
 27 {
 28     double real, image;
 29     Complex(double _real, double _image)
 30     {
 31         real = _real;
 32         image = _image;
 33     }
 34     Complex(){}
 35 };
 36 
 37 Complex operator + (const Complex &c1, const Complex &c2)
 38 {
 39     return Complex(c1.real + c2.real, c1.image + c2.image);
 40 }
 41 
 42 Complex operator - (const Complex &c1, const Complex &c2)
 43 {
 44     return Complex(c1.real - c2.real, c1.image - c2.image);
 45 }
 46 
 47 Complex operator * (const Complex &c1, const Complex &c2)
 48 {
 49     return Complex(c1.real*c2.real - c1.image*c2.image, c1.real*c2.image + c1.image*c2.real);
 50 }
 51 
 52 int rev(int id, int len)
 53 {
 54     int ret = 0;
 55     for(int i = 0; (1 << i) < len; i++)
 56     {
 57         ret <<= 1;
 58         if(id & (1 << i)) ret |= 1;
 59     }
 60     return ret;
 61 }
 62 
 63 Complex A[1 << 19];
 64 void FFT(Complex *a, int len, int DFT)
 65 {
 66     for(int i = 0; i < len; i++)
 67         A[rev(i, len)] = a[i];
 68     for(int s = 1; (1 << s) <= len; s++)
 69     {
 70         int m = (1 << s);
 71         Complex wm = Complex(cos(DFT*2*PI/m), sin(DFT*2*PI/m));
 72         for(int k = 0; k < len; k += m)
 73         {
 74             Complex w = Complex(1, 0);
 75             for(int j = 0; j < (m >> 1); j++)
 76             {
 77                 Complex t = w*A[k + j + (m >> 1)];
 78                 Complex u = A[k + j];
 79                 A[k + j] = u + t;
 80                 A[k + j + (m >> 1)] = u - t;
 81                 w = w*wm;
 82             }
 83         }
 84     }
 85     if(DFT == -1) for(int i = 0; i < len; i++) A[i].real /= len, A[i].image /= len;
 86     for(int i = 0; i < len; i++) a[i] = A[i];
 87     return;
 88 }
 89 
 90 Complex dis[1 << 19];
 91 bool ok[200010];
 92 
 93 int main()
 94 {
 95     int n, m;
 96     while(~scanf("%d", &n))
 97     {
 98         memset(ok, 0, sizeof(ok));
 99         int maxDis = 0;
100         int tmp;
101         for(int i = 0; i < n; i++)
102             scanf("%d", &tmp), ok[tmp] = 1, maxDis = max(maxDis, tmp);
103         for(int i = 0; i <= maxDis; i++)
104             if(ok[i]) dis[i] = Complex(1, 0);
105             else dis[i] = Complex(0, 0);
106         int len = 1;
107         while(len <= maxDis) len <<= 1;
108         len <<= 1;
109         for(int i = maxDis + 1; i < len; i++)
110             dis[i] = Complex(0, 0);
111         FFT(dis, len, 1);
112         for(int i = 0; i < len; i++)
113             dis[i] = dis[i]*dis[i];
114         FFT(dis, len, -1);
115         int ans = 0;
116         scanf("%d", &m);
117         for(int i = 0; i < m; i++)
118         {
119             scanf("%d", &tmp);
120             if(tmp <= maxDis*2 && (dis[tmp].real > 0.5 || ok[tmp]))
121                 ans++;
122         }
123         printf("%d\n", ans);
124         
125     }
126     return 0;
127 }
View Code

 

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