【FFT】 UVALIVE 6886 Golf Bot
题意:就是现在给出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 }