The main idea: given n items, you can use a/two/three different items to come up with different values, for each value of how many pieces of patchwork scheme (in different order)
First, get the mother function of these n objects.
Sum the square of each item of a to get the polynomial b
Sum the cubes of each of a to get the polynomial C
So if you don't think about order and repetition, then the number of schemes is a+b+c.
Now consider the order and repetition after
The number of three items is (A^3-3*A*B+2*C)/6
The number of two items is (a^2-b)/2
The number of options for an item is a
So the final answer is (a^3-3*a*b+2*c)/6+ (a^2-b)/2+a
Just use the FFT to get it right--
#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <
algorithm> #define M 132000 #define PI 3.1415926535897932 #define EPS 1e-3 using namespace std;
struct complex{double a,b; Complex () {} Complex (double _,double __): A (_), B (__) {} Complex operator + (const Complex &c) Const {return Co
Mplex (A+C.A,B+C.B);
} Complex Operator-(const Complex &c) Const {return Complex (A-C.A,B-C.B);
} Complex operator * (const Complex &c) Const {return Complex (A*C.A-B*C.B,A*C.B+B*C.A);
} void operator = = (Const Complex &c) {*this=*this+c;
} void Operator-= (const Complex &c) {*this=*this-c;
Friend Complex operator * (double X,complex c) {return Complex (c.a*x,c.b*x);
}
};
int n,m=131072;
Complex A[m],b[m],c[m],ans[m];
void FFT (Complex a[],int n,int type) {static Complex temp[m];
int i;
if (n==1) return;
for (i=0;i<n;i+=2) temp[i>>1]=a[i],temp[i+n>>1]=a[i+1]; MemCPY (a,temp,sizeof (Complex) *n);
Complex *l=a,*r=a+ (n>>1); FFT (L,n>>1,type);
FFT (R,n>>1,type);
Complex Root (cos (type*2*pi/n), sin (type*2*pi/n)), W (1,0);
for (I=0;i<n>>1;i++,w=w*root) temp[i]=l[i]+w*r[i],temp[i+ (n>>1)]=l[i]-w*r[i];
memcpy (a,temp,sizeof (Complex) *n);
int main () {int i,x;
cin>>n;
for (i=1;i<=n;i++) {scanf ("%d", &x);
A[x]=complex (1,0);
B[x*2]=complex (1,0);
C[x*3]=complex (1,0);
FFT (a,m,1);
FFT (b,m,1);
FFT (c,m,1);
for (i=0;i<m;i++) {ans[i]+= (1.0/6.0) * (a[i]*a[i]*a[i]-3*b[i]*a[i]+2*c[i));
ans[i]+= (0.5) * (A[i]*a[i]-b[i]);
Ans[i]+=a[i];
FFT (ans,m,-1);
for (i=0;i<m;i++) ans[i]= (1.0/m) *ans[i];
for (i=0;i<m;i++) {x=int (ans[i].a+eps);
if (x) printf ("%d%d\n", i,x);
return 0;
}