BZOJ3771: Triple - Problem Solving

https://www.lydsy.com/JudgeOnline/problem.php?id=3771

The main idea: given n axes of different values, choose one/two/three, and how many possible cases of each value sum constituted.

Generating function, the exponent is the value, and the coefficient is the number of possible cases.

But direct FFT multiplication will have two/three axes taking the same one.

So we store two more arrays, record the generation functions of two/three at the same time, and then just tolerate and deny it!

(Note that the order of taking it is the same, don't forget to remove it)

#include<cstdio>
#include<cctype>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;
typedef long double dl;
const dl pi=acos(-1.0);
const int N=3e5+5;
inline int read(){
    int X=0,w=0;char ch=0;
    while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
    while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}
struct complex{ // Define complex number 
    dl x,y;
    complex(dl xx=0.0,dl yy=0.0){
        x =xx;y= yy;
    }
    complex operator +(const complex &b)const{
        return complex(x+b.x,y+b.y);
    }
    complex operator -(const complex &b)const{
        return complex(x-b.x,y-b.y);
    }
    complex operator *(const complex &b)const{
        return complex(x*b.x-y*b.y,x*b.y+y*b.x);
    }
};
void FFT(complex a[],int n,int on){
    for(int i=1,j=n>>1;i<n-1;i++){
        if(i<j)swap(a[i],a[j]);
        int k=n>>1;
        while(j>=k){j-=k;k>>=1;}
        if(j<k)j+=k;
    }
    for(int i=2;i<=n;i<<=1){
        complex res(cos(-on*2*pi/i),sin(-on*2*pi/i));
        for(int j=0;j<n;j+=i){
            complex w(1,0);
            for(int k=j;k<j+i/2;k++){
                complex u=a[k],t=w*a[k+i/2];
                a[k]=u+t;
                a[k+i/2]=u-t;
                w=w*res;
            }
        }
    }
    if(on==-1)
        for(int i=0;i<n;i++)a[i].x/=n;
}
int n,m;
complex a[N],b[N],c[N],d[N];
int main(){
    n=read();
    for(int i=1;i<=n;i++){
    int w=read();m=max(m,w);
    a[w].x=1;
    b[w*2].x=1;
    c[w*3].x=1;
    }
    m=m*3;
    int nn=1;
    while(nn<m)nn<<=1;
    FFT(a,nn,1);FFT(b,nn,1);FFT(c,nn,1);
    for(int i=0;i<nn;i++){
    complex t1(1.0/2.0,0);
    complex t2(3.0,0);
    complex t3(2.0,0);
    complex t4(1.0/6.0,0);
    d[i]=d[i]+a[i];
    d[i]=d[i]+(a[i]*a[i]-b[i])*t1;
    d[i]=d[i]+(a[i]*a[i]*a[i]-t2*a[i]*b[i]+t3*c[i])*t4;
    }
    FFT(d,nn,-1);
    for(int i=0;i<m;i++){
    int w=d[i].x+0.5;
    if(w)printf("%d %d\n",i,w);
    }
    return 0;
}

+++++++++++++++++++++++++++++++++++++++++++

+ Author of this article: luyouqi233. +

+Welcome to my blog: http://www.cnblogs.com/luyouqi233/  +

+++++++++++++++++++++++++++++++++++++++++++

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325610655&siteId=291194637