BZOJ 3771 Triple FFT+容斥原理__fft

來源:互聯網
上載者:User
題意:連結 方法: FFT+容斥原理 解析: 這東西其實就是指數型母函數。 所以剛開始讀入的值我們都把它前面的係數置為1。 然後其實就是個多項式乘法了。 最大範圍顯然是讀入的值中的最大值乘三,對於本題的話是12W。 用FFT最佳化的話,達到了O(nlogn),顯然可過。 但是這裡有一個問題,就是如何處理重複的部分。 重複的部分我們考慮用容斥原理來解決。 為了方便描述我們不妨設三個多項式。 第一個是僅取一個而構成的多項式。->x 第二個是僅取相同的兩個而構成的多項式。->y 第三個是僅取相同的三個而構成的多項式。->z 對於本題有三種情況。 第一種是取一個,顯然直接將x加到答案就好。 第二種是取兩個,則需要一小步容斥,即(x*x-y)/2 第三種是取三個,則需要進一步容斥,即(x*x*x-3*x*y+2*z)/6 至於第三種,簡單說明一下,將x*x*x算上是代表了所有取三個的情況,減去3*x*y其實是減掉一個x*y/2,即選兩個相同的再除以排列數,因為大情況是3!重複,故添了個係數,減兩個相同的肯定包含三個相同的,所以要加回來兩個。 最後統計答案即可。 代碼:
#include <cmath>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define N 131072#define pi acos(-1)using namespace std;int n; struct complex{    double r,i;    complex(double x=0.0,double y=0.0){r=x,i=y;}    complex operator + (const complex a)    {return complex(a.r+r,a.i+i);}    complex operator - (const complex a)     {return complex(r-a.r,i-a.i);}    complex operator * (const complex a)    {return complex(r*a.r-i*a.i,r*a.i+i*a.r);}}a[N+10],b[N+10],c[N+10],d[N+10];int rev[N+10];void FFT(complex *a,int f){    for(int i=0;i<n;i++)if(i<rev[i])swap(a[i],a[rev[i]]);    for(int h=2;h<=n;h<<=1)    {        complex wn(cos(2*pi*f/h),sin(2*pi*f/h));        for(int i=0;i<n;i+=h)        {            complex w(1,0);            for(int j=0;j<(h>>1);j++,w=w*wn)            {                complex t=a[i+j+(h>>1)]*w;                a[i+j+(h>>1)]=a[i+j]-t;                a[i+j]=a[i+j]+t;            }        }    }    if(f==-1)for(int i=0;i<n;i++)a[i].r/=n;}int main(){    int ma=-1;    scanf("%d",&n);n--;    for(int i=0;i<=n;i++)    {        int x;        scanf("%d",&x);        a[x].r=1,b[2*x].r=1,c[3*x].r=1;        ma=max(ma,3*x);    }    int m=ma,L=0;    for(n=1;n<=m;n<<=1)L++;    for(int i=0;i<n;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(L-1));    FFT(a,1),FFT(b,1),FFT(c,1);    for(int i=0;i<=n;i++)    {        complex tmp(1.0/6.0,0);        complex tmp2(3.0,0);        complex tmp3(2.0,0);        complex tmp4(1.0/2.0,0);        d[i]=d[i]+(a[i]*a[i]*a[i]-tmp2*a[i]*b[i]+tmp3*c[i])*tmp;        d[i]=d[i]+(a[i]*a[i]-b[i])*tmp4;        d[i]=d[i]+a[i];    }    FFT(d,-1);     for(int i=0;i<=n;i++)    {        int print=(int)(d[i].r+0.1);        if(print!=0)printf("%d %d\n",i,print);    } }

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.