只要会了回滚莫队的话
这道题还是很好做的
不然的话就可能陷入普通莫队加线段树修改的O(n*sqrt(n)*logn)的误区
用双向链表实现
不过我写了半天也没有写出来
干脆就不写了
顺手再贴上dalao的优美代码(真实)
#include<iostream>
#include<ctime>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define my_min(a,b) ((a)<(b)?(a):(b))
#define my_max(a,b) ((a)>(b)?(a):(b))
using namespace std;
struct questions{
int l,r,xh;
questions(int _xh=0,int _l=0,int _r=0){ xh=_xh , l=_l , r=_r ; }
}qs[500005],que[500005];
bool cmp_l(const questions &a,const questions &b){ return a.l<b.l ; }
bool cmp_r(const questions &a,const questions &b){
if(a.r==b.r) return a.l<b.l ;
return a.r<b.r ;
}
int b_size , now_ans , qnum , stk[500005] , top , n , m , P[500005] ;
int ans[500005] , bl[500005] , br[500005] ;
bool has[500005] ;
int tag[500005] , TTT ;
inline void update(const int &a){
if(tag[a]!=TTT) tag[a]=TTT , has[a]=false , bl[a]=a , br[a]=a ;
}
void restore(){
while(top){
int t=stk[top] ;
if(t!=1&&has[t-1]) br[bl[t-1]]=t-1 ;
if(t!=n&&has[t+1]) bl[br[t+1]]=t+1 ;
has[t]=false , top-- ;
}
}
void get_it(int t,bool f){
update(t) , update(t-1) , update(t+1) ;
int ll=t,rr=t ;
if(t!=1&&has[t-1]) ll=bl[t-1] ;
if(t!=n&&has[t+1]) rr=br[t+1] ;
now_ans=my_max(now_ans,rr-ll+1) ;
br[ll]=rr , bl[rr]=ll , has[t]=true ;
if(f) stk[++top]=t ;
}
void solve(){
b_size=(int)(sqrt(n)+1e-8) ; ////////////////////////
sort(qs+1,qs+m+1,cmp_l) ;
int now=1 ;
for(int i=1;i<=n;i+=b_size){
now_ans=1 , qnum=0 ;
while(now<=m && qs[now].l>=i && qs[now].l<=my_min(n,i+b_size-1)) que[++qnum]=qs[now] , ++now ;
if(!qnum) continue ;
++TTT ;
//for(int j=1;j<=n;++j) has[j]=false , bl[j]=br[j]=j ; /////////////////////
sort(que+1,que+qnum+1,cmp_r) ;
int now_r=my_min(n,i+b_size-1) ;
for(int j=1;j<=qnum;++j){
while(now_r<que[j].r){
int t=P[++now_r] ;
get_it(t,false) ;
}
int t_ans=now_ans ;
for(int k=my_min(my_min(n,i+b_size-1),que[j].r);k>=que[j].l;--k){
int t=P[k] ;
get_it(t,true) ;
}
ans[que[j].xh]=now_ans , restore() ;
for(int k=my_min(my_min(n,i+b_size-1),que[j].r);k>=que[j].l;--k){ has[P[k]]=false ; }
now_ans=t_ans ;
}
}
for(int i=1;i<=m;++i) printf("%d\n",ans[i]) ;
}
int main()
{
freopen("ants.in","r",stdin) ;
freopen("ants.out","w",stdout) ;
scanf("%d%d",&n,&m) ;
for(int i=1;i<=n;++i) scanf("%d",&P[i]) ;
for(int i=1;i<=m;++i){
scanf("%d%d",&qs[i].l,&qs[i].r) ;
qs[i].xh=i ;
}
solve();
return 0 ;
}