A represents a number of scenarios
B means to take two identical
C means to take three identical
In the end, one is taken by a
Take Two is (A*a-b)/2
Take three is (A*A*A-3*A*B+2*Z)/6
A*a*a, you can use the FFT.
Multiplication is the convolution of a sequence
#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <algorithm
> #include <iostream> #define MAXN 200100 #define PI ACOs ( -1) using namespace std;
struct Yts {double r,i;
Yts operator+ (Yts x) {Yts ans;ans.r=r+x.r;ans.i=i+x.i;return ans;}
Yts operator-(Yts x) {Yts ans;ans.r=r-x.r;ans.i=i-x.i;return ans;} Yts operator* (Yts x) {Yts ans;ans.r=r*x.r-i*x.i;ans.i=r*x.i+i*x.r;return ans;}}
A[MAXN],B[MAXN],C[MAXN],D[MAXN],TEMP[MAXN];
Long Long ANS[3][MAXN];
int n,m,mx,digit;
int SEQ[MAXN];
void FFT (Yts x[],int n,int type) {if (n==1) return;
for (int i=0;i<n;i+=2) temp[i>>1]=x[i],temp[i+n>>1]=x[i+1];
memcpy (x,temp,sizeof (YTS) *n);
Yts *l=x,*r=l+ (n>>1); FFT (L,n>>1,type);
FFT (R,n>>1,type);
Yts root,w;
Root.r=cos (2*type*pi/n), Root.i=sin (2*type*pi/n);
w.r=1;w.i=0;
for (int i=0;i< (n>>1); i++,w=w*root) temp[i]=l[i]+w*r[i],temp[(n>>1) +i]=l[i]-w*r[i]; memcpy (x,temp,sizeof (YTS) *n);
int main () {scanf ("%d", &n);
for (int i=1;i<=n;i++) {int x;
scanf ("%d", &x);
Seq[i]=x;
a[x].r++;ans[0][x]++;
Mx=max (MX,X);
} mx*=3;
for (digit=1;digit<mx;digit<<=1);
FFT (a,digit,1);
for (int i=0;i<=digit;i++) b[i]=a[i]*a[i],c[i]=a[i]*a[i]*a[i]; FFT (b,digit,-1);
FFT (c,digit,-1);
for (int i=1;i<=n;i++) d[2*seq[i]].r++;
FFT (d,digit,1);
for (int i=0;i<=digit;i++) d[i]=d[i]*a[i];
FFT (d,digit,-1);
for (int i=0;i<=digit;i++) {ans[1][i]= (Long Long) (b[i].r/digit+0.5);
ans[2][i]= (Long Long) (c[i].r/digit+0.5) -3* (Long Long) (d[i].r/digit+0.5);
for (int i=1;i<=n;i++) ans[1][2*seq[i]]--, ans[2][3*seq[i]]+=2;
for (int i=0;i<=digit;i++) ans[1][i]/=2,ans[2][i]/=6; for (int i=0;i<=digit;i++) if (ans[0][i]+ans[1][i]+ans[2][i]>0) printf ("%d%lld\n", i,ans[0][i]+ans[1][i]+ans[2
][i]);
return 0; }