BZOJ4120 : [Baltic2015]Editor

活跃区的操作序列的优先级单调不上升,所以每次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;
}

  

posted @ 2015-06-25 10:17  Claris  阅读(259)  评论(0编辑  收藏  举报