Transmission door: http://www.spoj.com/problems/TSUM/
Thought: First regardless of i<j<k this condition
Construction of a polynomial a (x) =sigma X^a[i]
So the number of s=a[i]+a[j]+a[k] is the number of x^ (a[i]+a[j]+a[k]=s)
In order for the exponent to add, we make a (x) cubic
So the number is the coefficient of S ^3 in a (x)
Then, for convenience, the following omitted the index A[i]
A (x) ^3=∑x*x*x (is equal to three numbers) +3∑x*x*y (that is, two numbers are equal, the coefficient is 3 because there are 3 permutations) −6∑xyz (that is, 3 numbers are unequal, the coefficients are 6)
Now what we're going to get is ∑xyz.
where 3∑x*x*y=∑x*x*∑x (more than two identical)-∑x*x*x (three are the same)
Substituting for the original type deformation
∑xyz= (A (x) ^3-3*sigma (x*x) *sigma (x) +2*sigma (x*x*x))/6 (symbol suddenly stuck in ... )
And then you can have the FFT on it.
Recursion is too slow ....
#include <cmath> #include <cstdio> #include <cstring> #include <algorithm> #define LL Long
const INT maxn=1<<17;
const double pi=3.1415926535897932384626433832795;
using namespace Std; struct plex{double r,i;}
TMP[MAXN]; Plex operator + (Plex A,plex b) {return (Plex) {A.R+B.R,A.I+B.I};} Plex operator-(Plex A,plex b) {return (Plex) {a.r-b.r,a.i-
B.I};}
Plex operator * (Plex A,plex b) {return (Plex) {A.R*B.R-A.I*B.I,A.R*B.I+A.I*B.R};}
struct dft{Plex A[MAXN];
void FFT (int bg,int step,int size,int op) {if (size==1) return;
FFT (Bg,step<<1,size>>1,op), FFT (BG+STEP,STEP<<1,SIZE>>1,OP);
Plex W= (Plex) {1,0},t= (plex) {cos (2.0*pi/size), Sin (2.0*pi*op/size)};
int p=bg,p0=bg,p1=bg+step;
for (int i=0;i<size/2;i++) {TMP[P]=A[P0]+W*A[P1];
TMP[P+SIZE/2*STEP]=A[P0]-W*A[P1];
p+=step,p0+= (step<<1), p1+= (step<<1), w=w*t;
for (int i=bg;size;size--, i+=step) a[i]=tmp[i];
}}a,b,c;
int N,A[MAXN],B[MAXN],C[MAXN]; int main () {
scanf ("%d", &n);
for (int i=0,x;i<n;i++) scanf ("%d", &x), a[x+20000]++,b[x+x+40000]++,c[3*x+60000]++;
for (int i=0;i<maxn;i++) a.a[i].r=a[i],b.a[i].r=b[i],c.a[i].r=c[i];
A.fft (0,1,maxn,1), B.fft (0,1,maxn,1);
for (int i=0;i<maxn;i++) c.a[i]=a.a[i]* (a.a[i]*a.a[i]-(Plex) {3.0,0.0}*b.a[i]);
C.fft (0,1,maxn,-1);
for (int i=0;i<maxn;i++) {ll ans= ((LL) (c.a[i].r/maxn+0.5) +2*c[i])/6;
if (ans) printf ("%d:%i64d\n", I-60000,ans);
return 0; }
(∑x) 3−3 (∑x2) (∑x) +2∑x36