博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ 3509: [CodeChef] COUNTARI
阅读量:5035 次
发布时间:2019-06-12

本文共 2417 字,大约阅读时间需要 8 分钟。

3509: [CodeChef] COUNTARI

Time Limit: 40 Sec  Memory Limit: 128 MB
Submit: 883  Solved: 250
[][][]

Description

给定一个长度为N的数组A[],求有多少对i, j, k(1<=i<j<k<=N)满足A[k]-A[j]=A[j]-A[i]。

Input

第一行一个整数N(N<=10^5)。

接下来一行N个数A[i](A[i]<=30000)。

Output

一行一个整数。

Sample Input

10
3 5 3 6 3 4 10 4 5 2

Sample Output

9

HINT

Source

分析:

考虑枚举中间项$a[j]$,我们可以使用$FFT$快速计算$ik$的配对个数,但是这样显然是$O(Nmaxnumlgmaxnum)$的,还没有暴力跑的快...

所以可以考虑分块,对于$ijk$都在同一块内或者$ij$在一块或者$jk$在一块的情况我们预处理出来,这些的复杂度是$O(len*N)$的,然后$ik$位于和$j$不同快的情况我们用$FFT$来计算,这个的复杂度是$O(\frac {N}{len}*maxnumlgmaxnum)$的...

如此计算,块的大小大概开到3000~2000就可以过去了...

代码:

#include
#include
#include
#include
#include
using namespace std;const int maxn=100000+5,maxblock=50+5;const double pi=acos(-1);int n,N,m,L,blo,a[maxn],R[maxn],id[maxn],be[maxblock],en[maxblock],cnt[maxblock][maxn];long long ans;struct complex{ double r,i; inline complex(double a=0,double b=0): r(a),i(b) {}; inline complex operator + (const complex &a){ return complex(r+a.r,i+a.i); } inline complex operator - (const complex &a){ return complex(r-a.r,i-a.i); } inline complex operator * (const complex &a){ return complex(r*a.r-i*a.i,r*a.i+i*a.r); } }l[maxn],s[maxn];inline void FFT(complex *l,int f){ for(int i=0;i
R[i]) swap(l[i],l[R[i]]); for(int i=1;i
<<=1){ complex wn(cos(pi/i),f*sin(pi/i)); for(int j=0;j
<<1){ complex w(1,0); for(int k=0;k
>1]>>1)|((i&1)<<(L-1)); blo=min(int(sqrt(n)*10),n); for(int i=1;i<=n;i++) id[i]=(i-1)/blo+1; for(int i=1;i<=id[n];i++) be[i]=lower_bound(id+1,id+n+1,i)-id, en[i]=upper_bound(id+1,id+n+1,i)-id-1; memset(cnt,0,sizeof(cnt)); for(int i=1;i<=n;i++) cnt[id[i]][a[i]]++; for(int B=1;B<=id[n];B++){ for(int i=be[B];i<=en[B];i++){ cnt[B][a[i]]--; for(int j=be[B];j
=0) ans+=cnt[B][2*a[i]-a[j]]; } } memset(cnt,0,sizeof(cnt)); for(int i=1;i<=n;i++) cnt[0][a[i]]++; for(int B=1;B<=id[n];B++){ for(int i=be[B];i<=en[B];i++) cnt[0][a[i]]--; for(int i=be[B];i<=en[B];i++){ for(int j=be[B];j
=0) ans+=cnt[0][2*a[i]-a[j]]; } } memset(cnt,0,sizeof(cnt)); for(int i=1;i<=n;i++) cnt[0][a[i]]++; for(int B=id[n];B>=1;B--){ for(int i=be[B];i<=en[B];i++) cnt[0][a[i]]--; for(int i=be[B];i<=en[B];i++){ for(int j=i-1;j>=be[B];j--) if(2*a[j]-a[i]>=0) ans+=cnt[0][2*a[j]-a[i]]; } } for(int B=1;B<=id[n];B++){ for(int i=0;i

  


By NeighThorn

转载于:https://www.cnblogs.com/neighthorn/p/6574382.html

你可能感兴趣的文章
类模板 - C++快速入门45
查看>>
[转载]JDK的动态代理深入解析(Proxy,InvocationHandler)
查看>>
centos7 搭建vsftp服务器
查看>>
RijndaelManaged 加密
查看>>
Android 音量调节
查看>>
HTML&CSS基础学习笔记1.28-给网页添加一个css样式
查看>>
windows上面链接使用linux上面的docker daemon
查看>>
Redis事务
查看>>
Web框架和Django基础
查看>>
python中的逻辑操作符
查看>>
关于tomcat下startup.bat双击闪退的问题
查看>>
CSS兼容性常见问题总结
查看>>
HDU 1548 A strange lift (Dijkstra)
查看>>
每天一个小程序—0005题(批量处理图片大小)
查看>>
C# 启动进程和杀死进程
查看>>
tcp实现交互
查看>>
IIS的各种身份验证详细测试
查看>>
JavaScript特效源码(3、菜单特效)
查看>>
聊聊、Zookeeper Linux 单服务
查看>>
Linux常用命令总结
查看>>