zoukankan      html  css  js  c++  java
  • BZOJ 3771: Triple

    Description

    问所有三/二/一元组可能形成的组合.

    Sol

    FFT.

    利用生成函数直接FFT一下,然后就是计算,计算的时候简单的容斥一下.

    任意三个-3*两个相同的+2*全部相同的+任意两个-两个相同的+任意一个.

    Code

    /**************************************************************
        Problem: 3771
        User: BeiYu
        Language: C++
        Result: Accepted
        Time:1760 ms
        Memory:26684 kb
    ****************************************************************/
     
    #include <bits/stdc++.h>
    using namespace std;
     
    #define mpr make_pair
    #define rr first
    #define ii second
    typedef pair< double,double > Complex;
    const int N = 5e5+50;
    const int M = 40000;
    const double Pi = M_PI;
     
    Complex operator + (const Complex &a,const Complex &b) {
        return mpr(a.rr+b.rr,a.ii+b.ii);
    }
    Complex operator - (const Complex &a,const Complex &b) {
        return mpr(a.rr-b.rr,a.ii-b.ii);
    }
    Complex operator * (const Complex &a,const Complex &b) {
        return mpr(a.rr*b.rr-a.ii*b.ii,a.rr*b.ii+a.ii*b.rr);
    }
    Complex operator * (const Complex &a,const int &b) {
        return mpr(a.rr*b,a.ii*b);
    }
    Complex operator / (const Complex &a,const double &b) {
        return mpr(a.rr/b,a.ii/b);
    }
    int n;
    Complex a[N],b[N],c[N];
    int ans[N];
     
    void Rev(Complex a[]) {
        for(int i=0,j=0;i<n;i++) {
            if(i>j) swap(a[i],a[j]);
            for(int k=n>>1;(j^=k)<k;k>>=1);
        }
    }
    void DFT(Complex a[],int r) {
        Rev(a);
        for(int i=2;i<=n;i<<=1) {
            Complex wi=mpr(cos(2.0*Pi/i),r*sin(2.0*Pi/i));
            for(int k=0;k<n;k+=i) {
                Complex w=mpr(1.0,0.0);
                for(int j=k;j<k+i/2;j++) {
                    Complex t1=a[j],t2=w*a[j+i/2];
                    a[j]=t1+t2,a[j+i/2]=t1-t2;
                    w=w*wi;
                }
            }
        }if(r==-1) for(int i=0;i<n;i++) a[i].rr/=n;
    }
    void FFT(Complex a[],Complex b[],Complex c[]) {
        DFT(a,1),DFT(b,1);
        for(int i=0;i<n;i++) c[i]=a[i]*b[i];
        DFT(c,-1);
    }
    void init(int x) {
        for(n=1;n<x;n<<=1);
    }
    void Print(Complex a[]) {
        for(int i=0;i<n;i++) if((int)(a[i].rr+0.5)>=1) printf("%d %d
    ",i,int(a[i].rr+0.5));
    }
    int main() {
        int l;
        cin>>l;
        for(int i=1,x;i<=l;i++) cin>>x,a[x].rr+=1.0,b[x*2].rr+=1.0,c[x*3].rr+=1.0;
        init(M*3);
         
        DFT(a,1),DFT(b,1),DFT(c,1);
        for(int i=0;i<n;i++) a[i]=(a[i]*a[i]*a[i]-a[i]*b[i]*3+c[i]*2)/6.0+(a[i]*a[i]-b[i])/2.0+a[i];
        DFT(a,-1);
         
        Print(a);
        return 0;
    }
    

      

  • 相关阅读:
    git 常用命令
    svn常用命令
    mysql的bin或者sbin目录可执行文件
    SQL 函数
    SQL 通配符
    从一个Activity打开另外一个Activity
    断点下载数据
    多线程下载文件
    向服务器发送post请求
    android 查看网络图片
  • 原文地址:https://www.cnblogs.com/beiyuoi/p/6254870.html
Copyright © 2011-2022 走看看