HDU 3487 Play with Chain(SplayTree)
2014-04-27 19:44
423 查看
HDU 3487 Play with Chain(SplayTree)
http://acm.hdu.edu.cn/showproblem.php?pid=3487
分析:1到N的序列支持两种操作:
CUT a b c 将区间[a,b]的数删除,并接到新数列的第c个数后面
FLIP a b 将区间[a,b]的数翻转顺序
SplayTree基本操作.
AC代码:
http://acm.hdu.edu.cn/showproblem.php?pid=3487
分析:1到N的序列支持两种操作:
CUT a b c 将区间[a,b]的数删除,并接到新数列的第c个数后面
FLIP a b 将区间[a,b]的数翻转顺序
SplayTree基本操作.
AC代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define Key_Value ch[ch[root][1]][0] int n,q; const int maxn=300000+100; int pre[maxn],ch[maxn][2],rev[maxn],size[maxn],key[maxn],root,tot1; void Update_Rev(int r) { if(r==0) return ; swap(ch[r][0],ch[r][1]); rev[r]^=1; } void Push_Down(int r) { if(rev[r]) { Update_Rev(ch[r][0]); Update_Rev(ch[r][1]); rev[r]=0; } } void Push_Up(int r) { size[r]=1+size[ch[r][0]]+size[ch[r][1]]; } void New_Node(int &r,int fa,int k) { r=++tot1; pre[r]=fa; key[r]=k; rev[r]=ch[r][0]=ch[r][1]=0; size[r]=1; } void Build(int &x,int l,int r,int fa) { if(l>r)return ; int mid=(l+r)>>1; New_Node(x,fa,mid); Build(ch[x][0],l,mid-1,x); Build(ch[x][1],mid+1,r,x); Push_Up(x); } void Init() { root=tot1=0; key[root]=ch[root][0]=ch[root][1]=size[root]=rev[root]=pre[root]=0; New_Node(root,0,-1); New_Node(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) { while(pre[r]!=goal) { if(pre[pre[r]]==goal) Rotate(r,ch[pre[r]][0]==r); else { 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]]; if(k==t+1) return r; else if(k<=t) return Get_Kth(ch[r][0],k); else return Get_Kth(ch[r][1],k-t-1); } //本题操作 void CUT(int a,int b,int c) { Splay(Get_Kth(root,a),0); Splay(Get_Kth(root,b+2),root); int temp=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=temp; pre[Key_Value]=ch[root][1]; Push_Up(ch[root][1]); Push_Up(root); } void REVERSE(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 print(int r) { if(r==0)return ; Push_Down(r); print(ch[r][0]); if(cnt<n && key[r]>0) { cnt++; printf("%d",key[r]); if(cnt<n) printf(" "); else if(cnt==n) printf("\n"); } print(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 if(op[0]=='F') { scanf("%d%d",&x,&y); REVERSE(x,y); } } cnt=0; print(root); //Inorder(root); } return 0; }
相关文章推荐
- hdoj(hdu)-3487-play with the chain-SplayTree
- HDU 3487 Play with Chain
- hdu 3487 Play with Chain(伸展树)
- HDU 3487 Play with Chain (splay tree)
- 【HDU】3487 Play with Chain Splay
- HDU 3487(Play with Chain-Splay)[template:Splay]
- HDU 3487 Play with Chain(区间FLIP、CUT)
- HDU 3487 Play with Chain(Splay)
- HDU 3487 Play with Chain
- HDU 3487 Play with Chain
- hdu 3487 Play with Chain splay 区间翻转,插入,删除
- Play with Chain HDU - 3487 splay区间翻转,区间位移
- hdu-3487-Play with Chain-(splay 区间翻转,切割,插入)
- HDU 3487 Play with Chain | Splay
- hdu 3487 Play with Chain(Splay)
- HDU 3487-Play with Chain-splay
- hdu 3487 Play with Chain
- HDU-3487 Play with Chain (splay好题 带翻转 cut-link操作)
- hdu 3487 Play with Chain(splay)
- hdu 3487 Play with Chain splay