hdu-3487-Play with Chain-(splay 区间翻转,切割,插入)

题意:

区间翻转,切割,插入

// File Name: ACM/HDU/3487.cpp
// Author: Zlbing
// Created Time: 2013年08月10日 星期六 21时35分28秒 #include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<cmath>
#include<queue>
using namespace std;
#define CL(x,v); memset(x,v,sizeof(x));
#define INF 0x3f3f3f3f
#define LL long long
#define REP(i,r,n) for(int i=r;i<=n;i++)
#define RREP(i,n,r) for(int i=n;i>=r;i--)
#define L ch[x][0]
#define R ch[x][1]
#define KT (ch[ ch[rt][1] ][0])
const int MAXN = 3e5+;
struct SplayTree {
int sz[MAXN];
int ch[MAXN][];
int pre[MAXN];
int rt,top;
inline void down(int x){
if(flip[x]) {
flip[ L ] ^= ;
flip[ R ] ^= ;
swap(L,R);
flip[x]=;
}
}
inline void up(int x){
sz[x]=+sz[ L ] + sz[ R ];
}
inline void Rotate(int x,int f){
int y=pre[x];
down(y);
down(x);
ch[y][!f] = ch[x][f];
pre[ ch[x][f] ] = y;
pre[x] = pre[y];
if(pre[x]) ch[ pre[y] ][ ch[pre[y]][] == y ] =x;
ch[x][f] = y;
pre[y] = x;
up(y);
}
inline void Splay(int x,int goal){//将x旋转到goal的下面
down(x);////防止pre[x]就是目标点,下面的循环就进不去了,x的信息就传不下去了
while(pre[x] != goal){
down(pre[pre[x]]); down(pre[x]);down(x);//在旋转之前需要先下传标记,因为节点的位置可能会发生改变
if(pre[pre[x]] == goal) Rotate(x , ch[pre[x]][] == x);
else {
int y=pre[x],z=pre[y];
int f = (ch[z][]==y);
if(ch[y][f] == x) Rotate(x,!f),Rotate(x,f);
else Rotate(y,f),Rotate(x,f);
}
}
up(x);
if(goal==) rt=x;
}
inline void RTO(int k,int goal){//将第k位数旋转到goal的下面
int x=rt;
down(x);
while(sz[ L ]+ != k) {
if(k < sz[ L ] + ) x=L;
else {
k-=(sz[ L ]+);
x = R;
}
down(x);
}
Splay(x,goal);
}
void vist(int x){
if(x){
printf("结点%2d : 左儿子 %2d 右儿子 %2d %2d flip:%d\n",x,L,R,val[x],flip[x]);
vist(L);
vist(R);
}
}
void Newnode(int &x,int c,int f){
x=++top;flip[x]=;
L = R = ; pre[x] = f;
sz[x]=; val[x]=c;
}
inline void build(int &x,int l,int r,int f){
if(l>r) return ;
int m=(l+r)>>;
Newnode(x,m,f);
build(L , l , m- , x);
build(R , m+ , r , x);
pre[x]=f;
up(x);
} inline void init(int n){
ch[][]=ch[][]=pre[]=sz[]=;
rt=top=; flip[]=; val[]=;
Newnode(rt,-,);
Newnode(ch[rt][],-,rt);
sz[rt]=;
build(KT,,n,ch[rt][]);
}
void Del(){
int t=rt;
if(ch[rt][]) {
rt=ch[rt][];
RTO(,);
ch[rt][]=ch[t][];
if(ch[rt][]) pre[ch[rt][]]=rt;
}
else rt=ch[rt][];
pre[rt]=;
up(rt);
}
void solve1(int a,int b,int c)
{
RTO(a,);
RTO(b+,rt);
int tmp=KT;
KT=;
up(ch[rt][]);
up(rt); RTO(c+,);
RTO(c+,rt);
KT=tmp;
pre[tmp]=ch[rt][];
up(ch[rt][]);
up(rt);
}
void solve2(int a,int b)
{
RTO(a,);
RTO(b+,rt);
flip[KT]^=;
}
void print(int x)
{
if(x)
{
down(x);
print(L);
if(val[x]!=-)
{
if(flag)printf(" ");
flag=;
printf("%d",val[x]);
}
print(R);
}
}
void out()
{
flag=;
print(rt);
printf("\n");
}
int flip[MAXN];
int val[MAXN];
int flag;
}spt; int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
if(n==-)break;
char op[];
int a,b,c;
spt.init(n);
REP(i,,m)
{
scanf("%s",op);
if(op[]=='C')
{
scanf("%d%d%d",&a,&b,&c);
spt.solve1(a,b,c);
}
else
{
scanf("%d%d",&a,&b);
spt.solve2(a,b);
} }
spt.out();
}
return ;
}
上一篇:bzoj3223 Tyvj 1729 文艺平衡树(Splay Tree+区间翻转)


下一篇:MySQL中地理位置数据扩展geometry的使用心得