Splay进行区间处理 还没完全搞懂..
http://acm.hdu.edu.cn/showproblem.php?pid=3487
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
#define Key_value ch[ch[root][1]][0]
//根的右节点的左节点
const int MAXN = 300010;
int pre[MAXN],ch[MAXN][2],root,tot1;
int key[MAXN],rev[MAXN];
int size[MAXN];
int s[MAXN],tot2;
int n,q;
void NewNode(int &r,int father,int k)
{
if(tot2) r = s[tot2--];
else r = ++tot1;
key[r] = k;
pre[r] = father;
rev[r] = 0;
ch[r][0] = ch[r][1] = 0;
size[r] = 1;
}
//反转的更新
void Update_Rev(int r)
{
if(!r) return;
swap(ch[r][0],ch[r][1]);
rev[r] ^= 1;
}
void push_up(int r)
{
size[r] = size[ch[r][0]] + size[ch[r][1]] + 1;
}
void push_down(int r)
{
if(rev[r])
{
Update_Rev(ch[r][0]);
Update_Rev(ch[r][1]);
rev[r] = 0;
}
}
void Build(int &x,int l,int r,int father)
{
if(l > r)return;
int mid = (l+r)/2;
NewNode(x,father,mid);
Build(ch[x][0],l,mid-1,x);
Build(ch[x][1],mid+1,r,x);
push_up(x);
}
void Init()
{
root = tot1 = tot2 = 0;
ch[root][0] = ch[root][1] = size[root] = key[root] = pre[root] = rev[root] = 0;
NewNode(root,0,-1);
NewNode(ch[root][1],root,-1);
Build(Key_value,1,n,ch[root][1]);
push_up(ch[root][1]);
push_up(root);
}
void Rotate(int x,int kind)
{
int y = pre[x];
push_down(y);
push_down(x);
ch[y][!kind] = ch[x][kind];
pre[ch[x][kind]] = y;
if(pre[y])
ch[pre[y]][ch[pre[y]][1]==y] = x;
pre[x] = pre[y];
ch[x][kind] = y;
pre[y] = x;
push_up(y);
}
void Splay(int r,int goal)
{
push_down(r);
while(pre[r] != goal)
{
if(pre[pre[r]] == goal)
{
push_down(pre[r]);
push_down(r);
Rotate(r,ch[pre[r]][0]==r);
}
else
{
push_down(pre[pre[r]]);
push_down(pre[r]);
push_down(r);
int y = pre[r];
int kind = ch[pre[y]][0]==y;
if(ch[y][kind] == r)
{
Rotate(r,!kind);
Rotate(r,kind);
}
else
{
Rotate(y,kind);
Rotate(r,kind);
}
}
}
push_up(r);
if(goal == 0)root = r;
}
int Get_kth(int r,int k)
{
push_down(r);
int t = size[ch[r][0]] + 1;
if(t == k)return r;
if(t > k)return Get_kth(ch[r][0],k);
else return Get_kth(ch[r][1],k-t);
}
//将[l,r]段剪切下来,放在剩下段的第c个后面
void CUT(int l,int r,int c)
{
Splay(Get_kth(root,l),0);
Splay(Get_kth(root,r+2),root);
int tmp = Key_value;
Key_value = 0;
push_up(ch[root][1]);
push_up(root);
Splay(Get_kth(root,c+1),0);
Splay(Get_kth(root,c+2),root);
Key_value = tmp;
pre[Key_value] = ch[root][1];
push_up(ch[root][1]);
push_up(root);
}
//将[l,r]段反转
void FLIP(int l,int r)
{
Splay(Get_kth(root,l),0);
Splay(Get_kth(root,r+2),root);
Update_Rev(Key_value);
push_up(ch[root][1]);
push_up(root);
}
//按顺序输出
int cnt;
void InOrder(int r)
{
if(!r)return;
push_down(r);
InOrder(ch[r][0]);
if(cnt >=1 && cnt <= n)
{
printf("%d",key[r]);
if(cnt < n)printf(" ");
else printf("\n");
}
cnt++;
InOrder(ch[r][1]);
}
int main()
{
while(scanf("%d%d",&n,&q) == 2)
{
if( n < 0 && q < 0)break;
Init();
char op[20];
int x,y,z;
while(q--)
{
scanf("%s",op);
if(op[0] == 'C')
{
scanf("%d%d%d",&x,&y,&z);
CUT(x,y,z);
}
else
{
scanf("%d%d",&x,&y);
FLIP(x,y);
}
}
cnt = 0;
InOrder(root);
}
return 0;
}