伸展树hdu4453(good)
来源:互联网 发布:开淘宝网店怎么弄客服 编辑:程序博客网 时间:2024/05/16 17:13
Online JudgeOnline ExerciseOnline TeachingOnline ContestsExercise AuthorF.A.Q
Hand In Hand
Online Acmers
Forum | Discuss
Statistical ChartsBest Coder beta
VIP | STD Contests
Virtual Contests
DIY | Web-DIY beta
Recent Contests
Total Submission(s): 1377 Accepted Submission(s): 428
Hand In Hand
Online Acmers
Forum | Discuss
Statistical ChartsBest Coder beta
VIP | STD Contests
Virtual Contests
DIY | Web-DIY beta
Recent Contests
New~ 关于举办杭电程序设计竞赛(2014'12)的报名通知
【比赛提醒】BestCoder 你报名了吗?(点击报名)
【科普】什么是BestCoder?如何参加?
【比赛提醒】BestCoder 你报名了吗?(点击报名)
【科普】什么是BestCoder?如何参加?
Looploop
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1377 Accepted Submission(s): 428
Problem Description
XXX gets a new toy named Looploop. The toy has N elements arranged in a loop, an arrow pointing to one of the elements, and two preset parameters k1 and k2. Every element has a number on it.
The figure above shows a Looploop of 6 elments. Let's assuming the preset parameter k1 is 3, and k2 is 4.
XXX can do six operations with the toy.
1: add x
Starting from the arrow pointed element, add x to the number on the clockwise first k2 elements.
2: reverse
Starting from the arrow pointed element, reverse the first k1 clockwise elements.
3: insert x
Insert a new element with number x to the right (along clockwise) of the arrow pointed element.
4: delete
Delete the element the arrow pointed and then move the arrow to the right element.
5: move x
x can only be 1 or 2. If x = 1 , move the arrow to the left(along the counterclockwise) element, if x = 2 move the arrow to the right element.
6: query
Output the number on the arrow pointed element in one line.
XXX wants to give answers to every query in a serial of operations.
The figure above shows a Looploop of 6 elments. Let's assuming the preset parameter k1 is 3, and k2 is 4.
XXX can do six operations with the toy.
1: add x
Starting from the arrow pointed element, add x to the number on the clockwise first k2 elements.
2: reverse
Starting from the arrow pointed element, reverse the first k1 clockwise elements.
3: insert x
Insert a new element with number x to the right (along clockwise) of the arrow pointed element.
4: delete
Delete the element the arrow pointed and then move the arrow to the right element.
5: move x
x can only be 1 or 2. If x = 1 , move the arrow to the left(along the counterclockwise) element, if x = 2 move the arrow to the right element.
6: query
Output the number on the arrow pointed element in one line.
XXX wants to give answers to every query in a serial of operations.
Input
There are multiple test cases.
For each test case the first line contains N,M,k1,k2(2≤k1<k2≤N≤105, M≤105) indicating the initial number of elements, the total number of operations XXX will do and the two preset parameters of the toy.
Second line contains N integers ai(-104≤ai≤104) representing the N numbers on the elements in Looploop along clockwise direction. The arrow points to first element in input at the beginning.
Then m lines follow, each line contains one of the six operations described above.
It is guaranteed that the "x" in the "add","insert" and "move" operations is always integer and its absolute value ≤104. The number of elements will never be less than N during the operations.
The input ends with a line of 0 0 0 0.
For each test case the first line contains N,M,k1,k2(2≤k1<k2≤N≤105, M≤105) indicating the initial number of elements, the total number of operations XXX will do and the two preset parameters of the toy.
Second line contains N integers ai(-104≤ai≤104) representing the N numbers on the elements in Looploop along clockwise direction. The arrow points to first element in input at the beginning.
Then m lines follow, each line contains one of the six operations described above.
It is guaranteed that the "x" in the "add","insert" and "move" operations is always integer and its absolute value ≤104. The number of elements will never be less than N during the operations.
The input ends with a line of 0 0 0 0.
Output
For each test case, output case number in the first line(formatted as the sample output). Then for each query in the case, output the number on the arrow pointed element in a single line.
Sample Input
5 1 2 43 4 5 6 7query5 13 2 41 2 3 4 5move 2queryinsert 8reversequeryadd 2querymove 1querymove 1querydeletequery0 0 0 0
Sample Output
Case #1:3Case #2:2810151
这个题跟前面的都差不多,只不过是要处理循环的问题,可以先把前半段切下来然后拼接到后面,其他的都一样
#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<stack>#include<map>#include<set>#include<algorithm>#define Key_value ch[ch[root][1]][0]using namespace std;const int maxn=200010;int N,M,k1,k2,a[maxn],pos;int ch[maxn][2],pre[maxn],size[maxn],key[maxn],add[maxn],rev[maxn];int root,tot1,tot2,s[maxn];void NewNode(int &r,int f,int val){ if(tot2)r=s[tot2--]; else r=++tot1; ch[r][0]=ch[r][1]=0; pre[r]=f; size[r]=1; key[r]=val; rev[r]=0; add[r]=0;}void pushup(int r){ size[r]=size[ch[r][0]]+size[ch[r][1]]+1;}void build(int &x,int l,int r,int f){ if(l>r)return ; int mid=(l+r)>>1; NewNode(x,f,a[mid]); build(ch[x][0],l,mid-1,x); build(ch[x][1],mid+1,r,x); pushup(x);}void init(){ root=tot1=tot2=0; ch[root][0]=ch[root][1]=size[root]=key[root]=add[root]=pre[root]=0; rev[root]=0; NewNode(root,0,-1); NewNode(ch[root][1],root,-1); build(Key_value,1,N,ch[root][1]); pushup(ch[root][1]); pushup(root);}void update_add(int r,int x){ if(!r)return; add[r]+=x; key[r]+=x;}void update_rev(int r){ if(!r)return; swap(ch[r][1],ch[r][0]); rev[r]^=1;}void pushdown(int r){ if(add[r]) { update_add(ch[r][0],add[r]); update_add(ch[r][1],add[r]); add[r]=0; } if(rev[r]) { update_rev(ch[r][0]); update_rev(ch[r][1]); rev[r]=0; }}void Rotate(int x,int kind){ int y=pre[x]; pushdown(y); pushdown(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; pushup(y);}void Splay(int r,int goal){ pushdown(r); while(pre[r]!=goal) { if(pre[pre[r]]==goal) { pushdown(pre[r]); pushdown(r); Rotate(r,ch[pre[r]][0]==r); } else { pushdown(pre[pre[r]]); pushdown(pre[r]); pushdown(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); } } } pushup(r); if(goal==0)root=r;}int get_kth(int r,int k){ pushdown(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);}void change(int k){ Splay(pos,0); int tmp=size[ch[root][0]]+1; Splay(get_kth(root,1),0); Splay(get_kth(root,tmp),root); tmp=Key_value; Key_value=0; pushup(ch[root][1]); pushup(root); Splay(get_kth(root,size[root]-1),0); Key_value=tmp; pre[Key_value]=ch[root][1]; pushup(ch[root][1]); pushup(root); Splay(get_kth(root,1),0); Splay(get_kth(root,k+2),root);}void Add(int x){ change(k2); update_add(Key_value,x); pushup(ch[root][1]); pushup(root); pos=get_kth(root,2);}void Reverse(){ change(k1); update_rev(Key_value); pushup(ch[root][1]); pushup(root); pos=get_kth(root,2);}void Insert(int x){ Splay(pos,0); Splay(get_kth(root,size[ch[root][0]]+2),root); NewNode(Key_value,ch[root][1],x); pushup(ch[root][1]); pushup(root);}void erase(int r){ if(r) { s[++tot2]=r; erase(ch[r][0]); erase(ch[r][1]); }}void Delete(){ Splay(pos,0); int tmp=size[ch[root][0]]+1; Splay(get_kth(root,tmp-1),0); Splay(get_kth(root,tmp+1),root); erase(Key_value); pre[Key_value]=0; Key_value=0; pushup(ch[root][1]); pushup(root); if(tmp==size[root])pos=get_kth(root,2); else pos=get_kth(root,tmp);}void Move(int x){ if(x==1) { Splay(pos,0); int tmp=size[ch[root][0]]; if(size[ch[root][0]]==1)tmp=size[root]-1; pos=get_kth(root,tmp); } else { Splay(pos,0); int tmp=size[ch[root][0]]+2; if(tmp==size[root])tmp=2; pos=get_kth(root,tmp); }}void Query(){ Splay(pos,0); printf("%d\n",key[root]);}int main(){ char op[10]; int x,cas=1; while(scanf("%d%d%d%d",&N,&M,&k1,&k2)!=EOF) { if(!N&&!M&&!k1&&!k2)break; for(int i=1;i<=N;i++)scanf("%d",&a[i]); init(); pos=get_kth(root,2); printf("Case #%d:\n",cas++); while(M--) { scanf("%s",op); if(op[0]=='a') { scanf("%d",&x); Add(x); } else if(op[0]=='r') Reverse(); else if(op[0]=='i') { scanf("%d",&x); Insert(x); } else if(op[0]=='d') Delete(); else if(op[0]=='m') { scanf("%d",&x); Move(x); } else if(op[0]=='q')Query(); } } return 0;}
0 0
- 伸展树hdu4453(good)
- hdu4453 伸展树
- hdu4453 伸展树基本题
- HDU4453(伸展树模板题)
- hdu4453
- 伸展树(splay)
- 伸展树(转载)
- 伸展树(Splay)
- 伸展树:双层伸展
- 伸展树( splay tree)
- Splay Tree(伸展树)
- 伸展树(splay tree)
- 伸展树(Splay Tree)
- 伸展树(Splay tree)
- CODEVS 1286(伸展树)
- CODEVS 1343(伸展树)
- 伸展树
- 伸展树
- 黑马程序员──反射
- atitit.编程语言会形成进化树--哪些特性会繁荣??通才还是专才的选型 现代编程语言的特性总结
- foundation框架基础 NSMutableString 可变字符串
- 电力系统决策支持系统
- ListView中排序和分组(GroupTemplate)的使用实例演示
- 伸展树hdu4453(good)
- SQL总结(一)基本查询
- ios多态的感悟
- 文档处理 删除
- Source Insight使用配置[phunxm]
- 【iOS7的一些总结】15、单例设计模式
- Effecive Java 读书笔记(四)
- SQL总结(二)连表查询
- GIT学习笔记