您的位置:首页 > 理论基础 > 数据结构算法

Codevs_P2047 数据结构 1(SplayTree)

2016-02-04 10:56 429 查看
传送门

时间限制: 1 s

空间限制: 128000 KB

题目等级 : 钻石 Diamond

题目描述 Description

给一个长为N的数列,有M次操作

每次操作是将指定子序列移到整个序列最前端

输入描述 Input Description

第一行两个正整数:N和M

第二行N个整数表示这个数列

接下来M行每行两个正整数l和r表示将[l,r]移到整个数列最前端

输出描述 Output Description

一行,即M次操作后的数列

样例输入 Sample Input

5 2

1 2 3 4 5

2 3

2 3

样例输出 Sample Output

3 1 2 4 5

数据范围及提示 Data Size & Hint

1<=N<=10^5,1<=M<=10^5,输入保证合法,且所有整数可用带符号32位整型存储。

#include<cstdio>
#include<cstdlib>
#include<climits>
#include<iostream>
using namespace std;
struct Node{
Node *ch[2];
int r,v,s;
Node(int v,Node *nl):v(v){r=rand();ch[0]=ch[1]=nl;s=1;}
void maintain(){s=1;s+=ch[0]->s;s+=ch[1]->s;}
}*root,*null;
void rotate(Node* &o,int d){
Node *k=o->ch[d^1];o->ch[d^1]=k->ch[d];k->ch[d]=o;
o->maintain();k->maintain();o=k;
}
void insert(Node* &o,int x){
if(o==null){o=new Node(x,null);return;}
insert(o->ch[1],x);
if(o->ch[1]->r>o->r) rotate(o,0);
else o->maintain();
}
int cmprk(Node* o,int k){
if(o->ch[0]->s+1==k) return -1;
if(o->ch[0]->s>=k) return 0;else return 1;
}
void splay(Node* &o,int k){
if(o==null) return;
int d=cmprk(o,k);
if(d==1) k-=o->ch[0]->s+1;
if(d!=-1&&o->ch[d]!=null){
Node *p=o->ch[d];
int d2=cmprk(p,k);
if(d2!=-1&&p->ch[d2]!=null){
int k2=(d2==0?k:k-p->ch[0]->s-1);
splay(p->ch[d2],k2);
if(d==d2) rotate(o,d^1);else rotate(o->ch[d],d);
}
rotate(o,d^1);
}
}
Node *merge(Node *left,Node *right){//合并
splay(left,left->s);left->ch[1]=right;
left->maintain();return left;
}
void split(Node *o,int k,Node* &left,Node* &right){//分裂 前K小在left中其余在right中
if(k==0){
left=null,right=o;return;
}
if(k==o->s){
left=o,right=null;return;
}
splay(o,k);left=o;right=o->ch[1];
o->ch[1]=null;left->maintain();
}
void init(){
null=new Node(0,0);null->r=INT_MAX;null->s=null->v=0;
null->ch[0]=null->ch[1]=null;root=null;
}
void print(Node *o){
if(o==null) return;
print(o->ch[0]);
printf("%d ",o->v);
print(o->ch[1]);
}
int n,m,x,l,r;Node *rr,*lr,*ll,*rl;
int main(){
scanf("%d%d",&n,&m);init();
for(int i=1;i<=n;i++){
scanf("%d",&x);
insert(root,x);
}
//  print(root);putchar('\n');
while(m--){
scanf("%d%d",&l,&r);
split(root,r,rl,rr);
split(rl,l-1,ll,lr);
rl=merge(lr,ll);
root=merge(rl,rr);
//      print(root);putchar('\n');
}
print(root);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: