伸展树模版真的好长好长。。。
cut a b c:把第a-1个数伸展到根节点,把第b+1个数伸展到a的右子树,然后把ch[ch[root][1][0]]拿掉,放在剩下的树的第c个节点下。
flip a b:把第a-1个数伸展到根节点,把第b+1个数伸展到a的右子树,然后翻转ch[ch[root][1][0]];
由于会出现操作两边的情况,所以加了两个-1节点。
注意:
1,输出的时候要注意空格和换行。
2,在拿掉子树的时候要注意push_up();
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<vector> using namespace std; #define maxn 330000 #define mem(a,b) memset(a,b,sizeof(a)) #define root10 ch[ch[root][1]][0] #define root1 ch[root][1] int pre[maxn],ch[maxn][2],root,tot; int size[maxn]; int rev[maxn]; int key[maxn]; int n; void Treaval(int x) { if(x) { Treaval(ch[x][0]); printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d ,key = %2d \n",x,ch[x][0],ch[x][1],pre[x],size[x],key[x]); Treaval(ch[x][1]); } } void debug() {printf("%d\n",root);Treaval(root);} //以上Debug void init() { root=tot=0; mem(pre,0); mem(ch,0); mem(size,0); mem(rev,0); } void newnode(int &x,int k,int father) { x=++tot; pre[x]=father; size[x]=1; ch[x][0]=ch[x][1]=0; rev[x]=0; key[x]=k; } void push_down(int x) { if(rev[x]) { rev[x]=0; rev[ch[x][0]]^=1; rev[ch[x][1]]^=1; swap(ch[x][0],ch[x][1]); } } void push_up(int x) { size[x]=size[ch[x][0]]+size[ch[x][1]]+1; } void rot(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); push_up(x); } void splay(int x,int goal) { push_down(x); while(pre[x]!=goal) { if(pre[pre[x]]==goal) { push_down(pre[x]); push_down(x); rot(x,ch[pre[x]][0]==x); } else { int y=pre[x]; push_down(pre[y]); push_down(y); push_down(x); int kind=ch[pre[y]][0]==y; if(ch[y][kind]==x) { rot(x,!kind); rot(x,kind); } else { rot(y,kind); rot(x,kind); } } } push_up(x); if(goal==0)root=x; } void buildtree(int &x,int l,int r,int father) { if(l>r)return ; int mid=(l+r)/2; newnode(x,mid,father); buildtree(ch[x][0],l,mid-1,x); buildtree(ch[x][1],mid+1,r,x); push_up(x); } int get_kth(int x,int k) { push_down(x); int p=size[ch[x][0]]; if(p+1==k)return x; else if(k<=p)return get_kth(ch[x][0],k); else get_kth(ch[x][1],k-p-1); } int get_min(int r){ push_down(r); while(ch[r][0]){ r=ch[r][0]; push_down(r); } return r; } int get_max(int r){ push_down(r); while(ch[r][1]){ r=ch[r][1]; push_down(r); } return r; } void cut(int a,int b,int c) { int x=get_kth(root,a); int y=get_kth(root,b+2); splay(x,0); splay(y,root); int t=root10; root10=0; push_up(root1); push_up(root); int z=get_kth(root,c+1); splay(z,0); int p=get_min(root1); splay(p,root); root10=t; pre[root10]=root1; push_up(root1); push_up(root); } void flip(int a,int b) { int x=get_kth(root,a); int y=get_kth(root,b+2); splay(x,0); splay(y,root); rev[root10]^=1; } vector<int>vec; void print(int x) { if(x==0)return; push_down(x); print(ch[x][0]); if(key[x]!=-1)vec.push_back(key[x]); print(ch[x][1]); } int main() { int m,a,b,c; char str[110]; int i; while(scanf("%d%d",&n,&m)&&(n+1||m+1)) { init(); newnode(root,-1,0); newnode(ch[root][1],-1,root); size[root]=2; buildtree(root10,1,n,root1); push_up(root1); push_up(root); for(i=1;i<=m;i++) { scanf("%s",str); if(str[0]==‘C‘) { scanf("%d%d%d",&a,&b,&c); cut(a,b,c); } else { scanf("%d%d",&a,&b); flip(a,b); } } vec.clear(); print(root); for(i=0;i<vec.size();i++) { cout<<vec[i]; if(i!=vec.size()-1)cout<<" "; else cout<<endl; } } return 0; }
再解Java中的String,码迷,mamicode.com
原文地址:http://blog.csdn.net/chenssy/article/details/24602641