splay的区间翻转,splay(l-1,f[rot]),splay(r+1,rot);
之后将ch[ch[rot][1]][0]的子树翻转
理论简单,操作闹腾...
附上代码,splay区间操作入门题
1 #include2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 using namespace std; 9 #define N 10005010 #define get(rt) (ch[f[rt]][0]!=rt)11 #define PushUp(rt) if(rt)siz[rt]=siz[ch[rt][0]]+siz[ch[rt][1]]+112 int ch[N][2],f[N],siz[N],val[N];13 int rot,n,Q;14 bool tag[N];15 void PushDown(int x)16 { 17 if(!tag[x])return ;18 tag[x]=0;19 swap(ch[x][0],ch[x][1]);20 tag[ch[x][0]]^=1;21 tag[ch[x][1]]^=1; 22 }23 void rotate(int rt)24 {25 int x=f[rt],y=f[x],b=get(rt);26 ch[x][b]=ch[rt][b^1];f[ch[x][b]]=x;ch[rt][b^1]=x;f[x]=rt;f[rt]=y;27 if(y)ch[y][ch[y][0]!=x]=rt;28 PushUp(x);PushUp(rt);29 if(rot==x)rot=rt;30 }31 void splay(int rt,int y)32 {33 for(int fa;(fa=f[rt])!=y;rotate(rt))34 {35 if(f[fa]!=y)36 {37 rotate((get(rt)==get(fa))?fa:rt);38 }39 }40 }41 int find(int x)42 {43 int now=rot;44 while(1)45 {46 PushDown(now);47 if(x<=siz[ch[now][0]])now=ch[now][0];48 else49 {50 x-=siz[ch[now][0]]+1;51 if(!x)return now;52 now=ch[now][1];53 }54 }55 }56 void build(int fa,int l,int r)57 {58 if(l>r)return ;59 int m=(l+r)>>1;60 ch[fa][m>fa]=m;61 siz[m]=1;62 val[m]=m-1;63 f[m]=fa;64 build(m,l,m-1);65 build(m,m+1,r);66 PushUp(m);67 }68 void reverse(int x,int y)69 {70 x=find(x);71 y=find(y);72 splay(x,f[rot]);73 splay(y,rot);74 tag[ch[y][0]]^=1;75 }76 int main()77 {78 scanf("%d%d",&n,&Q);79 build(0,1,n+2);80 rot=(n+3)>>1;81 for(int i=1;i<=Q;i++)82 {83 int x,y;84 scanf("%d%d",&x,&y);85 reverse(x,y+2);86 }87 for(int i=2;i<=n;i++)printf("%d ",val[find(i)]);88 printf("%d\n",val[find(n+1)]);89 }