这个水题应该算是用splay处理区间问题的入门了吧。。。昨天从早晨到晚上一直都在考虑优先级的问题,后来看到网上大神说的才理解,在splay的区间问题里,做价值的并不是数值而是他在整个区间的下标也就是第几个,这个理解了以后今天早晨看的标程写的。。。
下面是代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAX 100005
using 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_right
down(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;
}