P6006 [USACO20JAN]Farmer John Solves 3SUM G 题解
BF_AlphaShoot · · 题解
题目传送门。
善良的出题人已经在题面中告诉你了:
尚未发现运行速度比平方时间明显更优的解法。
而
思考在暴力
在面对
可惜的是这会导致你 MLE。应该把数组
本题代码细节较恶心,故意跟数组过不去,应格外注意:
-
查找
-s_i-s_j 时要加上常数M ,因为数组不能访问负的,会数组越界。 -
-
桶应该开为
2\times M ,如果较小可能会因为+M 而数组越界。
View code:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ri register int
#define il inline
const int N=5010,M=2e6+10;
int n,Q;
int s[N],b[M<<1];
ll f[N][N];
il ll read(){
ll x=0,y=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-')
y=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=x*10+c-'0';
c=getchar();
}
return x*y;
}
il void work(){
for(ri i=1;i<=n;i++){
for(ri j=i+1;j<=n;j++){
f[i][j]=b[M-s[i]-s[j]];
b[s[j]+M]++;
}
for(ri j=i+1;j<=n;j++)
b[s[j]+M]=0;
}
for(ri i=3;i<=n;i++){
for(ri j=1;j<=n-i+1;j++){
int k=i+j-1;
f[j][k]+=f[j+1][k]+f[j][k-1]-f[j+1][k-1];
}
}
}
signed main(){
n=read(),Q=read();
for(ri i=1;i<=n;i++)
s[i]=read();
work();
while(Q--){
int a=read(),b=read();
printf("%lld\n",f[a][b]);
}
return 0;
}