dirty机房训练赛-ants

只要会了回滚莫队的话

这道题还是很好做的

不然的话就可能陷入普通莫队加线段树修改的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 ;
}

猜你喜欢

转载自blog.csdn.net/ENESAMA/article/details/83065191
今日推荐