UVALive - 6886 Golf Bot (FFT)
阿新 • • 發佈:2018-09-26
type init etc pre lin push set back i++
題意:給N個數a[i],再給M個數,問這M個數中有多少滿足:出現在N個數中或能表示成某兩個數之和.
分析:FFT求出能夠生成的數的系數,給出的M個數若在生成的項中系數不為0,則計數+1
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int MAXN = 4e5 + 10; const double PI = acos(-1.0); struct Complex{ double x, y; inline Complex operator+(const Complex b) const { return (Complex){x +b.x,y + b.y}; } inline Complex operator-(const Complex b) const { return (Complex){x -b.x,y - b.y}; } inline Complex operator*(const Complex b) const { return (Complex){x *b.x -y * b.y,x * b.y + y * b.x}; } } va[MAXN * 2 + MAXN / 2], vb[MAXN * 2 + MAXN / 2]; int lenth = 1, rev[MAXN * 2 + MAXN / 2]; int N, M; // f 和 g 的數量 //f g和 的系數 // 卷積結果 // 大數乘積 int f[MAXN],g[MAXN]; vector<LL> conv; vector<LL> multi; //f g void init() { int tim = 0; lenth = 1; conv.clear(), multi.clear(); memset(va, 0, sizeof va); memset(vb, 0, sizeof vb); while (lenth <= N + M - 2) lenth <<= 1, tim++; for (int i = 0; i < lenth; i++) rev[i] = (rev[i >> 1] >> 1) + ((i & 1) << (tim - 1)); } void FFT(Complex *A, const int fla) { for (int i = 0; i < lenth; i++){ if (i < rev[i]){ swap(A[i], A[rev[i]]); } } for (int i = 1; i < lenth; i <<= 1){ const Complex w = (Complex){cos(PI / i), fla * sin(PI / i)}; for (int j = 0; j < lenth; j += (i << 1)){ Complex K = (Complex){1, 0}; for (int k = 0; k < i; k++, K = K * w){ const Complex x = A[j + k], y = K * A[j + k + i]; A[j + k] = x + y; A[j + k + i] = x - y; } } } } void getConv() { init(); for (int i = 0; i < N; i++) va[i].x = f[i]; for (int i = 0; i < M; i++) vb[i].x = g[i]; FFT(va, 1), FFT(vb, 1); for (int i = 0; i < lenth; i++) va[i] = va[i] * vb[i]; FFT(va, -1); for (int i = 0; i <= N + M - 2; i++) conv.push_back((LL)(va[i].x / lenth + 0.5)); } void getMulti() { getConv(); multi = conv; reverse(multi.begin(), multi.end()); multi.push_back(0); int sz = multi.size(); for (int i = 0; i < sz - 1; i++){ multi[i + 1] += multi[i] / 10; multi[i] %= 10; } while (!multi.back() && multi.size() > 1) multi.pop_back(); reverse(multi.begin(), multi.end()); } int a[MAXN]; int cnt[MAXN]; int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif int n; int m; while(scanf("%d",&n)==1){ int mx = 0; memset(cnt,0,sizeof(cnt)); for(int i=1;i<=n;++i){ scanf("%d",&a[i]); cnt[a[i]]=1; mx = max(mx,a[i]); } for(int i=0;i<=mx;++i){ f[i] = g[i] = cnt[i]; } N = M = mx+1; getConv(); scanf("%d",&m); int sum; LL res=0; for(int i=1;i<=m;++i){ scanf("%d",&sum); if(sum<=mx*2 && (conv[sum]|| cnt[sum])) res++; } printf("%lld\n",res); } return 0; }
UVALive - 6886 Golf Bot (FFT)