bzoj3223==tyvj1729 文艺平衡树

来源:互联网 发布:linux目录结构图 编辑:程序博客网 时间:2024/05/22 05:18

这个水题应该算是用splay处理区间问题的入门了吧。。。昨天从早晨到晚上一直都在考虑优先级的问题,后来看到网上大神说的才理解,在splay的区间问题里,做价值的并不是数值而是他在整个区间的下标也就是第几个,这个理解了以后今天早晨看的标程写的。。。

下面是代码

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define MAX 100005using namespace std;int n,i,m,tot=0,top=0;int size[MAX],child[MAX][2],father[MAX],value[MAX],res[MAX];int root=0,num=0;int a[MAX];void down(int x){if(!x)return;if(!res[x])return;if(child[x][0])res[child[x][0]]^=1;if(child[x][1])res[child[x][1]]^=1;res[x]=0;swap(child[x][0],child[x][1]);}void rotate(int p){int q=father[p],y=father[q],x=(child[q][1]==p);//if p is q's right person then x==1 else x==0//if x==1 then rotate_left//else if x==0 then rotate_rightdown(q);down(p);//pay attention !father[child[q][x]=child[p][x^1]]=q;father[child[p][x^1]=q]=p;father[p]=y;//res[p]=0;if(y) child[y][child[y][1]==q]=p;size[q]=1+size[child[q][0]]+size[child[q][1]];size[p]=1+size[child[p][0]]+size[child[p][q]];//pay more attention = = -> the size of p,q should re_calc}void splay(int x,int aim=0){down(x);for(int y;(y=father[x])!=aim;rotate(x)) if(father[y]!=aim)  {  if((child[y][0]==x)==(child[father[y]][0]==y))        rotate(y);      else     rotate(x);  }if(aim==0)  root=x;size[x]=size[child[x][0]]+1+size[child[x][1]];}/*int ask(int x,int k)//select{k--;for(;;) { if(x==0)   return 0; if(size[child[x][1]]<=k&&k<cnt[x]+size[child[x][1]])   return x; if(size[child[x][1]]>k)   x=child[x][1]; else  {  k-=cnt[x]+size[child[x][1]];  x=child[x][0];  } }}void up_date(int x){if(!x)return;if(res[x]){res[x]=0;swap(child[x][1],child[x][0]);swap(value[child[x][0]],value[child[x][1]]);res[child[x][1]]=!res[child[x][1]];res[child[x][0]]=!res[child[x][0]];}}void reserve(int l,int r){splay(ask(root,n-(l-1)+1));splay(ask(root,n-(r+1)+1),root);child[child[root][1]][0]^=1;up_date(child[child[root][1]][0]);}*/void print(int x){//cout<<"print="<<x<<endl;if(!x)return;down(x);print(child[x][0]);printf("%d ",value[x]);print(child[x][1]);return;}void update(int x){if(!x)return;size[x]=size[child[x][0]]+size[child[x][1]]+1;}int select(int k){int t=root;while(1){down(t);if(size[child[t][0]]+1==k)break;if(k<=size[child[t][0]])t=child[t][0];    else{k-=size[child[t][0]]+1;t=child[t][1];}}return t;}void build(int &x,int l,int r){if(l>r){x=0;return;}int mid=(l+r)/2;tot++;x=tot;size[x]=1;res[x]=0;value[x]=a[mid];build(child[x][0],l,mid-1);build(child[x][1],mid+1,r);if(child[x][0])father[child[x][0]]=x;    if(child[x][1])father[child[x][1]]=x;update(x);}void debug(){for(int k=1;k<=tot;k++)printf("%d %d %d %d\n",k,father[k],child[k][0],child[k][1]);}int main(){scanf("%d%d",&n,&m);for(i=1;i<=n+2;i++) a[i]=i-1;root=tot=0;size[0]=0;build(root,1,n+2);//debug();int y1,y2;for(i=1;i<=m;i++){scanf("%d%d",&y1,&y2);splay(select(y1));splay(select(y2+2),root);res[child[child[root][1]][0]]^=1;down(child[child[root][1]][0]);}splay(select(1));splay(select(n+2),root);print(child[child[root][1]][0]);    printf("\n");return 0;}

原创粉丝点击