zoukankan      html  css  js  c++  java
  • 【BZOJ3509】【CodeChef】—COUNTARI(分块+FFT)

    传送门

    BZOJBZOJ看不了权限题怎么办?
    把网址中的problemproblem改成showshow就可以了(虽然没法提交)
    可以从darkbzojdarkbzoj上下数据啊

    考虑处理22个东西
    l[i][j]l[i][j]表示ii前面,值为jj的个数,r[i][j]r[i][j]表示ii后面,值为jj的个数

    ans=i=1nj=0max(a)l[i][j]r[i][2a[i]j]ans=sum_{i=1}^{n}sum_{j=0}^{max(a)}l[i][j]*r[i][2*a[i]-j]

    发现这是一个卷积的形式,但直接fftfft也不行

    考虑分块对于当前块统计这个块前的ll,块后的rr
    对于有在块内的再重新统计

    块大小大约在nlognsqrt {nlogn}最佳
    复杂度O(nnlogn)O(nsqrt{nlogn})

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    inline int read(){
    	char ch=getchar();
    	int res=0,f=1;
    	while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=getchar();
    	return res*f;
    }
    const int N=100005;
    const int M=120005;
    const double pi=acos(-1);
    struct plx{
    	double x,y;
    	plx(double _x=0,double _y=0):x(_x),y(_y){}
    	friend inline plx operator +(const plx &a,const plx &b){
    		return plx(a.x+b.x,a.y+b.y);
    	}
    	friend inline plx operator -(const plx &a,const plx &b){
    		return plx(a.x-b.x,a.y-b.y);
    	}
    	friend inline plx operator *(const plx &a,const plx &b){
    		return plx(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);
    	}
    }A[N],B[N];
    int rev[M],lim=1,tim=0;
    inline void fft(plx f[],int kd){
    	for(int i=0;i<lim;i++)if(i<rev[i])swap(f[i],f[rev[i]]);
    	for(int mid=1;mid<lim;mid<<=1){
    		plx now=plx(cos(pi/mid),kd*sin(pi/mid));
    		for(int i=0;i<lim;i+=(mid<<1)){
    			plx w=plx(1,0);
    			for(int j=0;j<mid;j++,w=w*now){
    				plx a0=f[i+j],a1=w*f[i+j+mid];
    				f[i+j]=a0+a1,f[i+j+mid]=a0-a1;
    			}
    		}
    	}
    	if(kd==-1)for(int i=0;i<lim;i++)f[i].x/=lim;
    }
    int n,a[N],L[N],R[N],mx,cnt,blo,l[M],r[M];
    ll ans;
    int main(){
    	n=read(),blo=2000,cnt=(n-1)/blo+1;
    	for(int i=1;i<=n;i++)a[i]=read(),r[a[i]]++,mx=max(mx,a[i]);
    	while(lim<=mx*2)lim<<=1,tim++;
    	for(int i=0;i<lim;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(tim-1));
    	for(int i=1;i<=cnt;i++)L[i]=(i-1)*blo+1,R[i]=i*blo;R[cnt]=n;
    	for(int i=1;i<=cnt;i++){
    		for(int j=L[i];j<=R[i];j++)r[a[j]]--;
    		for(int j=0;j<lim;j++)A[j]=B[j]=plx(0,0);
    		for(int j=1;j<=mx;j++)A[j]=plx(l[j],0),B[j]=plx(r[j],0);
    		fft(A,1),fft(B,1);
    		for(int j=0;j<lim;j++)A[j]=A[j]*B[j];
    		fft(A,-1);
    		for(int j=L[i];j<=R[i];j++)ans+=(ll)(A[2*a[j]].x+0.5);
    		for(int j=L[i];j<=R[i];j++){
    			for(int k=L[i];k<j;k++)
    				if(2*a[j]-a[k]>0)ans+=r[2*a[j]-a[k]];
    			for(int k=j+1;k<=R[i];k++)
    				if(2*a[j]-a[k]>0)ans+=l[2*a[j]-a[k]];
    			l[a[j]]++;
    		}
    	}
    	cout<<ans<<'
    ';
    }
    
  • 相关阅读:
    关于postgresql——常用操作指令
    linux 下查看机器是cpu是几核的
    ASP.NET跨平台实践:无需安装Mono的Jexus“独立版”
    .NET平台开源项目速览(4).NET文档生成工具ADB及使用
    Hadoop学习---安装部署
    c# 模拟表单提交,post form 上传文件、大数据内容
    半小时学会上传本地项目到github
    统计网卡TX(发送)RX(接受)流量脚本
    mysql mysqldump只导出表结构或只导出数据的实现方法
    psutil--跨平台的进程管理
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/11145610.html
Copyright © 2011-2022 走看看