RT,
部分变量解释:
book[] 去重数组
siz 块长
bnum 块的数量
bfst[] 暴力求解中维护的第一次出现的位置
st[] lst[] 分别为维护出现第一次的位置和最后一次的位置
bl[] br[] 块的左右端点
bel[] 所属块的编号
con 贡献
rcon 右指针r产生的贡献
#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+1;
struct query{
int l,r,id;
}q[maxn];
int n,m,ans[maxn],a[maxn],book[maxn];
int siz,bnum,bfst[maxn],st[maxn],lst[maxn],clr[maxn],bl[maxn],br[maxn],bel[maxn];
inline bool cmp(query x,query y){
if (bel[x.l]!=bel[y.l]) return bel[x.l]<bel[y.l];
return x.r<y.r;
}
inline int bf(int l,int r){
int res=0;
for (int i=l;i<=r;i++) bfst[a[i]]=0;
for (int i=l;i<=r;i++){
if (bfst[a[i]]) res=max(res,i-bfst[a[i]]);
else bfst[a[i]]=i;
}
return res;
}
int main(){
scanf("%d",&n);
siz=sqrt(n);
bnum=ceil((double)n/siz);
for (int i=1;i<=bnum;i++){
bl[i]=(i-1)*siz+1;
br[i]=i*siz;
for (int j=bl[i];j<=br[i];j++) bel[j]=i;
}
br[bnum]=n;
for (int i=1;i<=n;i++){
scanf("%d",&a[i]);
book[i]=a[i];
}
sort(book+1,book+n+1);
int tot=unique(book+1,book+n+1)-book-1;
for (int i=1;i<=n;i++) a[i]=lower_bound(book+1,book+tot+1,a[i])-book;
scanf("%d",&m);
for (int i=1;i<=m;i++){
scanf("%d%d",&q[i].l,&q[i].r);
q[i].id=i;
}
sort(q+1,q+m+1,cmp);
for (int i=1,j=1;j<=bnum;j++){
int l=br[j]+1,r=br[j],con=0,p=0;
for (;bel[q[i].l]==j;i++){
if (bel[q[i].r]==j){
ans[q[i].id]=bf(q[i].l,q[i].r);
continue;
}
while (r<q[i].r){
r++;
lst[a[r]]=r;
if (!st[a[r]]){
st[a[r]]=r;
clr[++p]=a[r];
}else con=max(con,r-st[a[r]]);
}
int rcon=con;
while (l>q[i].l){
l--;
if (!lst[a[l]]) lst[a[l]]=l;
else con=max(con,lst[a[l]]-l);
}
ans[q[i].id]=con;
while (l<=br[j]){
if (lst[a[l]]==l) lst[a[l]]=0;
l++;
}
con=rcon;
}
for (int k=1;k<=p;k++) lst[clr[k]]=st[clr[k]]=0;
}
for (int i=1;i<=m;i++) printf("%d\n",ans[i]);
return 0;
}
九九九敏敏敏qwq