回滚数组
作者:互联网
应用:
解决方便加但是不方便减的情况,反之亦然
思路:
- 更具莫队的老排序,来排
- 然后对于 l.pos==r.pos 直接暴力做就行了
- 对于 这个区间的l.pos!=上面那个区间的, 就要把L,R重新弄一个空区间 L=R[LSTPOS]+1,R=R[pos];
- 特别注意 r 是<R[pos], 你的del和add要特别注意处理,更具题目的情况
- r<=p[i].r 就直接处理, 这个是莫队共用的
- l 弄一个那个l_ 处理一下,然后把 l_玩在弄回去,返回那个初始情况,滚动, 这个不是莫队共用,相当于上面的暴力
#include <bits/stdc++.h> using namespace std; #define ri register int #define M 1000005 int pos[M]; struct dain{ int l,r; int id; int ps; bool operator <(const dain &t)const { if(ps==t.ps) return r<t.r; return ps<t.ps; } }p[M]; bool cmp(dain &a,dain &b) { if(pos[a.l]==pos[b.l]) return a.r<b.r; return pos[a.l]<pos[b.l]; } int tmp=0; int n,m; int t[M],val[M]; int L[M],R[M]; int cur[M]; int ANS[M]; int ll[M],rr[M]; void del(int a) { a=val[a]; ll[a]=rr[a]=0; } int mx; void add(int a) { int b=a; a=val[a]; if(ll[a]==0) ll[a]=b; rr[a]=b; mx=max(rr[a]-ll[a],mx); } void addl(int a) { int b=a; a=val[a]; if(cur[a]) tmp=max(tmp,cur[a]-b); else cur[a]=b; if(rr[a]) tmp=max(tmp,rr[a]-b); } int main(){ ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); cin>>n; for(ri i=1;i<=n;i++) cin>>t[i],val[i]=t[i]; sort(t+1,t+1+n); int d=unique(t+1,t+1+n)-t-1; for(ri i=1;i<=n;i++) { val[i]=lower_bound(t+1,t+d+1,val[i])-t; } cin>>m; int sz=sqrt(n); int tot=n/sz; for(ri i=1;i<=tot;i++) { L[i]=(i-1)*sz+1; R[i]=i*sz; } if(R[tot]<n) L[++tot]=R[tot-1]+1,R[tot]=n; for(ri i=1;i<=tot;i++) { for(ri j=L[i];j<=R[i];j++) { pos[j]=i; } } for(ri i=1;i<=m;i++) { cin>>p[i].l>>p[i].r; p[i].id=i; p[i].ps=pos[p[i].l]; } sort(p+1,p+1+m); int l=1,r=0,lstpos=0; for(ri i=1;i<=m;i++) { if(pos[p[i].l]==pos[p[i].r]) { tmp=0; for(ri j=p[i].l;j<=p[i].r;j++) { if(cur[val[j]]) tmp=max(tmp,j-cur[val[j]]); else cur[val[j]]=j; } ANS[p[i].id]=tmp; for(ri j=p[i].l;j<=p[i].r;j++) { cur[val[j]]=0; } } else { if(pos[p[i].l]!=lstpos) { lstpos=pos[p[i].l]; while(r>R[lstpos]) del(r--); r=R[lstpos]; while(l<R[lstpos]+1) del(l++); mx=0; } tmp=0; while(r<p[i].r) add(++r); int l_=l; while(l_>p[i].l) addl(--l_); ANS[p[i].id]=max(tmp,mx); while(l_<l) { cur[val[l_]]=0; l_++; } } } for(ri i=1;i<=m;i++) cout<<ANS[i]<<endl; return 0; }View Code
后记:
- 全局变量和局部变量不要弄混淆了,不要定义一个相同的数字
- l_和 add() l_是相同的!!!
标签:回滚,lstpos,int,pos,id,数组,莫队,ri 来源: https://www.cnblogs.com/Lamboofhome/p/16550144.html