回滚莫队板子题16pts +WA+TLE求助
查看原帖
回滚莫队板子题16pts +WA+TLE求助
310773
PCCP楼主2023/7/8 14:51

这是非常简单的莫队板题,但是蒟蒻WA+TLE了。

我维护了左右端点的位置,回滚时把左端点赋回向右扩展后的值。

蒟蒻已经调了一整天了,求求谷内各位大佬帮帮蒟蒻吧!蒟蒻可以提供1关注。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
const int N=2e5+10;
int n,m,d,a[N],dfo[N];
vector<int> q;
struct node{
	int l,r,lb,rb,num;
}que[N];
bool cmp(node x,node y){
	if(x.lb==y.lb){
		return x.r<y.r;
	}
	return x.l<y.l;
}
int teml[N],temr[N],temans,forl[N],forr[N],ans,res[N];
void addright(int x){
	if(!forl[dfo[x]]){
		forl[dfo[x]]=x;
	}
	forr[dfo[x]]=x;
	ans=max(ans,forr[dfo[x]]-forl[dfo[x]]);
}
void addleft(int x){
	if(!forr[dfo[x]]){
		forr[dfo[x]]=x;
	}
	forl[dfo[x]]=x;
	ans=max(ans,forr[dfo[x]]-forl[dfo[x]]);
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		q.push_back(a[i]);
	}
	sort(q.begin(),q.end());
	q.erase(unique(q.begin(),q.end()),q.end());
	for(int i=1;i<=n;i++){
		dfo[i]=lower_bound(q.begin(),q.end(),a[i])-q.begin();
	}
	scanf("%d",&m);
	d=ceil((double)n*1.0/sqrt(m));
	for(int i=1;i<=m;i++){
		scanf("%d%d",&que[i].l,&que[i].r);
		que[i].lb=(que[i].l-1)/d+1,que[i].rb=(que[i].r-1)/d+1,que[i].num=i;
	}
	sort(que+1,que+m+1,cmp);
	int l=1,r=0,lastblock=0;
	for(int i=1;i<=m;i++){
		if(que[i].lb==que[i].rb){
			temans=0;
			for(int j=que[i].l;j<=que[i].r;j++){
				teml[dfo[j]]=temr[dfo[j]]=0;
			}
			for(int j=que[i].l;j<=que[i].r;j++){
				if(!teml[dfo[j]]){
					teml[dfo[j]]=j;
				}
				temr[dfo[j]]=j;
				temans=max(temans,temr[dfo[j]]-teml[dfo[j]]);
			}
			res[que[i].num]=temans;
			for(int j=que[i].l;j<=que[i].r;j++){
				teml[dfo[j]]=temr[dfo[j]]=0;
			}
			continue;
		}
		if(que[i].lb!=lastblock){
			while(r>(que[i].lb)*d){
				forl[dfo[r]]=forr[dfo[r]]=0;
				--r;
			}
			while(l<(que[i].lb)*d+1){
				forl[dfo[l]]=forr[dfo[l]]=0;
				++l;
			}
			forl[dfo[r]]=forr[dfo[r]]=0;
			forl[dfo[l]]=forr[dfo[l]]=0;
			ans=0;
		}
		if(que[i].r>r){
			while(que[i].r>r){
				addright(++r);
				teml[dfo[r]]=forl[dfo[r]];
			}
		}
		temans=ans;
		while(l>que[i].l){
			addleft(--l);
		}
		res[que[i].num]=ans;
		ans=temans;
		while(l<que[i].lb*d+1){
			forl[dfo[l]]=teml[dfo[l]];
			if(forr[dfo[l]]==l){
				forr[dfo[l]]=forl[dfo[l]]=0;
			}
			l++;
		}
	}
	for(int i=1;i<=m;i++){
		printf("%d\n",res[i]);
	}
}
2023/7/8 14:51
加载中...