活跃区的操作序列的优先级单调不上升,所以每次undo的一定是一段区间。
以优先级为权值建立可持久化权值线段树,维护优先级在某区间内的最靠后的位置。
#include<cstdio>
const int N=300010,M=6000000;
int n,i,j,x,f[N],root[N],v[M],l[M],r[M],tot;
inline void read(int&a){
char c;bool f=0;a=0;
while(!((((c=getchar())>='0')&&(c<='9'))||(c=='-')));
if(c!='-')a=c-'0';else f=1;
while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';
if(f)a=-a;
}
inline int max(int a,int b){return a>b?a:b;}
int ins(int x,int a,int b,int c,int d){
int y=++tot;v[y]=max(v[x],d);
if(a==b)return y;
int mid=(a+b)>>1;
if(c<=mid)l[y]=ins(l[x],a,mid,c,d),r[y]=r[x];else l[y]=l[x],r[y]=ins(r[x],mid+1,b,c,d);
return y;
}
int ask(int x,int a,int b,int c){
if(!x)return 0;
if(b<=c)return v[x];
int mid=(a+b)>>1,t=ask(l[x],a,mid,c);
if(c>mid)t=max(t,ask(r[x],mid+1,b,c));
return t;
}
int main(){
for(read(n),i=1;i<=n;printf("%d\n",f[i++])){
read(x);
if(x>0)f[i]=x,root[i]=ins(root[i-1],0,n,0,i);
else f[i]=f[j=ask(root[i-1],0,n,-x-1)-1],root[i]=ins(root[j],0,n,-x,i);
}
return 0;
}