回滚莫队
cpp
namespace MoRollBack{
// 回滚莫队,改work
struct Node{
int id,l,r;
};
// be块编号,[L,R]块边界
vector<int> be,L,R;
// block块大小, tot块数量
int block,tot;
vector<Node> que; // 询问
vector<pair<int&,int>> his;// 回滚辅助数组
bool cmp(const Node &x,const Node &y){
return (be[x.l]^be[y.l])?be[x.l]<be[y.l]:x.r<y.r;
}
void init(int n){
block=sqrt(n);
tot=(n+block-1)/block;
be.assign(n+1,0);
L.assign(tot+1,0);
R.assign(tot+1,0);
his.clear();
que.clear();
for(int i=1;i<=tot;i++){
L[i]=block*(i-1)+1,R[i]=min(block*i,n);
for(int j=L[i];j<=R[i];j++)be[j]=i;
}
}
void add_query(int l,int r){
int id=que.size();
que.push_back({id,l,r});
}
void Set(int &x,int y){
his.push_back({x,x});
x=y;
}
void rollback(int t=0){
while(his.size()>t){
auto [x,y]=his.back();
x=y;
his.pop_back();
}
}
}
using namespace MoRollBack;
void solve(){
int n;
cin>>n;
vector<int> nums,w(n+1);
for(int i=1;i<=n;i++)cin>>w[i],nums.push_back(w[i]);
sort(nums.begin(),nums.end());
nums.erase(unique(nums.begin(),nums.end()),nums.end());
for(int i=1;i<=n;i++)w[i]=lower_bound(nums.begin(),nums.end(),w[i])-nums.begin();
init(n);
int m;
cin>>m;
for(int i=0;i<m;i++){
int l,r;
cin>>l>>r;
add_query(l,r);
}
auto work=[&](){
sort(que.begin(),que.end(),cmp);
vector<int> mx(nums.size()),mn(nums.size());
vector<int> ans(que.size());
auto add=[&](int x,int &res){
if(!mx[w[x]]){
Set(mx[w[x]],x);
Set(mn[w[x]],x);
}
else{
if(x>mx[w[x]])Set(mx[w[x]],x);
if(x<mn[w[x]])Set(mn[w[x]],x);
}
if(mx[w[x]]-mn[w[x]]>res)Set(res,mx[w[x]]-mn[w[x]]);
};
for(int i=0,j;i<m;i++){
j=i;
while(j+1<m&&be[que[j].l]==be[que[j+1].l])j++;
int right=R[be[que[i].l]];
while(i<=j&&que[i].r<=right){
auto [id,ql,qr]=que[i++];
int res=0;
for(int k=ql;k<=qr;k++)add(k,res);
ans[id]=res;
rollback();
}
int res=0,l=right+1,r=right;
while(i<=j){
auto [id,ql,qr]=que[i++];
while(r<qr)add(++r,res);
int t=his.size();
while(l>ql)add(--l,res);
ans[id]=res;
l=right+1;
rollback(t);
}
rollback();
i=j;
}
return ans;
};
for(auto &x:work())cout<<x<<"\n";
}