先类似计数排序一样求一下数的个数,求一下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);} // head struct 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; }