zoukankan      html  css  js  c++  java
  • BZOJ 3509 [CodeChef] COUNTARI ——分块 FFT

    分块大法好。

    块内暴力,块外FFT。

    弃疗了,抄SX队长$silvernebula$的代码

    #include <map>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define F(i,j,k) for (int i=j;i<=k;++i)
    #define D(i,j,k) for (int i=j;i>=k;--i)
    #define ll long long
    #define mp make_pair
    #define maxn 200005
     
    struct Complex{
        double x,y;
        Complex (){}
        Complex (double _x,double _y){x=_x;y=_y;}
        Complex operator + (Complex a){return Complex(x+a.x,y+a.y);}
        Complex operator - (Complex a){return Complex(x-a.x,y-a.y);}
        Complex operator * (Complex a){return Complex(x*a.x-y*a.y,x*a.y+y*a.x);}
    }A[maxn],B[maxn],C[maxn];
     
    int rev[maxn],T,len,w[maxn],cnt=0,L[maxn],R[maxn],N,n,Rc[maxn],Lc[maxn];
    ll ans;
    const double pi=acos(-1.0);
     
    void FFT(Complex * x,int n,int flag)
    {
        F(i,0,n-1) if (rev[i]>i) swap(x[rev[i]],x[i]);
        for (int m=2;m<=n;m<<=1)
        {
            Complex wn=Complex(cos(2*pi/m),flag*sin(2*pi/m));
            for (int i=0;i<n;i+=m)
            {
                Complex w=Complex(1.0,0);
                for (int j=0;j<(m>>1);++j)
                {
                    Complex u=x[i+j],v=x[i+j+(m>>1)]*w;
                    x[i+j]=u+v;x[i+j+(m>>1)]=u-v;w=w*wn;
                }
            }
        }
        if (flag==-1) F(i,0,n-1) x[i].x/=n;
    }
     
    void solve(int id)
    {
        int x;
        F(i,L[id],R[id])
        {
            --Rc[w[i]];
            F(j,L[id],i-1){x=w[i]*2-w[j];if(x>=0)ans+=Rc[x];}
            F(j,i+1,R[id]){x=w[i]*2-w[j];if(x>=0)ans+=Lc[x];}
        }
        if (id>1&&id<cnt)
        {
            memset(A,0,sizeof A);
            memset(B,0,sizeof B);
            F(i,1,L[id]-1) A[w[i]].x+=1;
            F(i,R[id]+1,n) B[w[i]].x+=1;
            FFT(A,N,1);FFT(B,N,1);
            F(i,0,N-1)A[i]=A[i]*B[i];FFT(A,N,-1);
            F(i,L[id],R[id]) ans+=(ll)(A[w[i]<<1].x+0.3);
        }
        F(i,L[id],R[id]) ++Lc[w[i]];
    }
     
    int main()
    {
        scanf("%d",&n);F(i,1,n)scanf("%d",&w[i]);T=2000;cnt=0;
        while (cnt*T<n) L[++cnt]=R[cnt-1]+1,R[cnt]=cnt*T;
        R[cnt]=min(R[cnt],n);for(N=1,len=0;N<=60000;N<<=1)len++;
        F(i,0,N-1) rev[i]=(rev[i>>1]>>1)|((i&1)<<(len-1));
        D(i,n,1) Rc[w[i]]++; F(i,1,cnt) solve(i);
        printf("%lld
    ",ans);
    }
    

      

  • 相关阅读:
    洛谷P3811题解
    洛谷P3353在你窗外闪耀的星星-题解
    Map根据value来排序
    java8 groupby count
    Java反射
    maven profile环境切换
    获取nginx代理情况下的真实ip
    获取request里header的name和value
    git 删除iml文件
    java list 排序
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6776451.html
Copyright © 2011-2022 走看看