zoukankan      html  css  js  c++  java
  • 【bzoj4836】[Lydsy1704月赛]二元运算

    题目链接
    其实就是一个FFT的题。
    我们搞出两个生成函数A和B。
    对于第二种情况,我们直接把B序列反序,跑FFT就行了。第一种情况,有一个乘法的限制,我们跑分治FFT就好了。时间复杂度O(n(log2n)2)
    代码

     #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #pragma GCC optimize(3)
    using namespace std;
    const int N=140005;
    const double pi=3.141592653589793;
    typedef long long ll;
    int t,n,m,q,x,maxn,rev[N];
    ll ans[N];
    struct complex{
        double x,y;
        complex(){}
        complex(double x,double y):x(x),y(y){}
        friend complex operator + (complex a,complex b){
            return complex(a.x+b.x,a.y+b.y);
        }
        friend complex operator - (complex a,complex b){
            return complex(a.x-b.x,a.y-b.y);
        }
        friend complex operator * (complex a,complex b){
            return complex(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);
        }
    }a[N],b[N],c[N],d[N],e[N],tmp[N];
    void fft(complex a[],int n,int dft){
        for(int i=0;i<n;i++){
            rev[i]=(rev[i>>1]>>1)|((i&1)*(n>>1));
            if(i<rev[i]){
                swap(a[i],a[rev[i]]);
            }
        }
        for(int i=1;i<n;i<<=1){
            complex wn(cos(pi/i),dft*sin(pi/i));
            for(int j=0;j<n;j+=(i<<1)){
                complex w(1,0),x,y;
                for(int k=j;k<j+i;k++,w=w*wn){
                    x=a[k];
                    y=w*a[k+i];
                    a[k]=x+y;
                    a[k+i]=x-y;
                }
            }
        }
        if(dft==-1){
            for(int i=0;i<n;i++){
                a[i].x/=n;
            }
        }
    }
    void cdq(int l,int r){
        if(l==r){
            return;
        }
        int mid=(l+r)/2,n;
        for(n=1;n<=r-l-1;n<<=1);
        for(int i=0;i<n;i++){
            b[i].x=c[i].x=d[i].x=b[i].y=c[i].y=d[i].y=0;
        }
        for(int i=l;i<=mid;i++){
            b[i-l]=a[i];
        }
        for(int i=mid+1;i<=r;i++){
            c[i-mid-1]=tmp[i];
        }
        fft(b,n,1);
        fft(c,n,1);
        for(int i=0;i<n;i++){
            d[i]=b[i]*c[i];
        }
        fft(d,n,-1);
        for(int i=0;i<=r-l-1;i++){
            ans[l+mid+1+i]+=(ll)(d[i].x+0.5);
        }
        cdq(l,mid);
        cdq(mid+1,r);
    }
    int main(){
        scanf("%d",&t);
        while(t--){
            scanf("%d%d%d",&n,&m,&q);
            memset(a,0,sizeof(a));
            memset(b,0,sizeof(b));
            memset(c,0,sizeof(c));
            memset(d,0,sizeof(d));
            memset(e,0,sizeof(e));
            memset(tmp,0,sizeof(tmp));
            memset(ans,0,sizeof(ans));
            maxn=0;
            for(int i=1;i<=n;i++){
                scanf("%d",&x);
                maxn=max(maxn,x);
                a[x].x++;
            }
            for(int i=1;i<=m;i++){
                scanf("%d",&x);
                maxn=max(maxn,x);
                tmp[x].x++;
            }
            for(int i=0;i<=maxn;i++){
                b[maxn-i]=tmp[i];
            }
            for(int i=0;i<=maxn;i++){
                c[i]=a[i];
                d[i]=b[i];
            }
            fft(c,131072,1);
            fft(d,131072,1);
            for(int i=0;i<131072;i++){
                e[i]=c[i]*d[i];
            }
            fft(e,131072,-1);
            for(int i=0;i<=maxn;i++){
                ans[i]=(ll)(e[i+maxn].x+0.5);
            }
            cdq(0,maxn);
            while(q--){
                scanf("%d",&x);
                printf("%lld
    ",ans[x]);
            }
        }
        return 0;
    }
  • 相关阅读:
    C++实现数字媒体三维图像渲染
    C++实现数字媒体三维图像变换
    C++实现数字媒体二维图像变换
    C++实现glut绘制点、直线、多边形、圆
    语音识别之梅尔频谱倒数MFCC(Mel Frequency Cepstrum Coefficient)
    Java中的BigDecimal类精度问题
    spring 手册
    bootstrap 参考文档
    springBoot入门文章
    JNDI
  • 原文地址:https://www.cnblogs.com/2016gdgzoi471/p/9476840.html
Copyright © 2011-2022 走看看