【FFT】 SPOJ Triple Sums

来源:互联网 发布:java趣味编程100例pdf 编辑:程序博客网 时间:2024/05/30 04:48

先类似计数排序一样求一下数的个数,求一下p的3次方的卷积,然后类似容斥一样减去重复的就可以了。。。。

#include <iostream>#include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <algorithm> #include <cstring> #include <climits>#include <cstdlib>#include <cmath>#include <time.h>#define maxn 300005#define maxm 1000005#define eps 1e-10#define mod 1000000007#define INF 999999999#define PI (acos(-1.0))#define lowbit(x) (x&(-x))#define mp make_pair#define ls o<<1#define rs o<<1 | 1#define lson o<<1, L, mid #define rson o<<1 | 1, mid+1, R#pragma comment(linker, "/STACK:16777216")typedef long long LL;typedef unsigned long long ULL;//typedef int LL;using namespace std;LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;}LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;}void scanf(int &__x){__x=0;char __ch=getchar();while(__ch==' '||__ch=='\n')__ch=getchar();while(__ch>='0'&&__ch<='9')__x=__x*10+__ch-'0',__ch = getchar();}LL gcd(LL _a, LL _b){if(!_b) return _a;else return gcd(_b, _a%_b);}// headstruct complex{double r, i;complex(double r = 0, double i = 0) : r(r), i(i) {}complex operator + (complex b) const {return complex(r + b.r, i + b.i);}complex operator - (complex b) const {return complex(r - b.r, i - b.i);}complex operator * (complex b) const {return complex(r * b.r - i * b.i, r * b.i + i * b.r);}}A[maxn], B[maxn];void fft(complex y[], int len, int on){for(int i = 1, j = len / 2; i < len-1; i++) {if(i < j) swap(y[i], y[j]);int k = len / 2;while(j >= k) {j -= k;k /= 2;}j += k;}for(int i = 2; i <= len; i <<= 1) {complex wn(cos(-on * 2 * PI / i), sin(-on * 2 * PI / i));for(int j = 0; j < len; j += i) {complex w(1, 0);for(int k = j; k < j + i / 2; k++) {complex u = y[k];complex t = y[k + i / 2] * w;y[k] = u + t;y[k + i / 2] = u - t;w = w * wn;}}}if(on == -1) for(int i = 0; i < len; i++) y[i].r /= len;}  const int base = 20000;const complex three = complex(3.0, 0);int a[maxn];int b[maxn];int c[maxn];int mx, n;int cmp(int a, int b){return a < b;}void init(void){memset(a, 0, sizeof a);memset(b, 0, sizeof b);memset(c, 0, sizeof c);}void read(void){int x;mx = -INF;for(int i = 0; i < n; i++) {scanf("%d", &x);x += base;mx = max(mx, x);a[x]++;b[x + x]++;c[x + x + x]++;}}void work(void){int len1 = mx+1, len = 1;while(len < 4 * len1) len <<= 1;for(int i = 0; i < len; i++) A[i] = complex(a[i], 0);for(int i = 0; i < len; i++) B[i] = complex(b[i], 0);fft(A, len, 1);fft(B, len, 1);for(int i = 0; i < len; i++) A[i] = A[i] * (A[i] * A[i] - three * B[i]);fft(A, len, -1);for(int i = 0; i < len; i++) {int ans = ((int)(A[i].r + 0.5) + 2 * c[i]) / 6;if(ans) printf("%d : %d\n", i - base * 3, ans);}}int main(void){while(scanf("%d", &n) != EOF) {init();read();work();}return 0;}


0 0