HDU 4453 Looploop(SplayTree)
来源:互联网 发布:md5加密 java代码 编辑:程序博客网 时间:2024/06/08 16:05
HDU 4453 Looploop(SplayTree)
http://acm.hdu.edu.cn/showproblem.php?pid=4453
分析:
add x 操作:从队首开始的的连续k2个数都加上x值.
reverse 操作: 从队首开始的连续k1个数都翻转
insert x 操作:在第一个元素与第二个元素之间插入一个x值
delete 操作: 删除队首的元素
move 1操作:队尾元素插入0(队首位置)
move 2操作:队首元素插入队尾
query 操作: 返回队首元素的值
不过这题要注意的是,由于是循环队列,当执行add和reverse操作的时候,要先把指针前面的那一段截断,接到SplayTree后面去,这样我们就可以解决这个循环的问题.
AC代码:
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=200000+10;#define Key_Value ch[ch[root][1]][0]int pre[maxn],size[maxn],rev[maxn],add[maxn],ch[maxn][2];int root,tot1,tot2,s[maxn],key[maxn];int n,q,k1,k2;int a[maxn];int tp;void New_Node(int &r,int fa,int k){ if(tot2) r=s[tot2--]; else r=++tot1; key[r]=k; pre[r]=fa; add[r]=rev[r]=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 Update_Add(int r,int val){ if(!r) return; key[r]+=val; add[r]+=val;}void Push_Up(int r){ size[r]=1+size[ch[r][0]]+size[ch[r][1]];}void Push_Down(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 Build(int &x,int l,int r,int fa){ if(l>r)return; int mid=(l+r)>>1; New_Node(x,fa,a[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; pre[root]=size[root]=rev[root]=add[root]=key[root]=ch[root][0]=ch[root][1]=0; New_Node(root,0,-1); New_Node(ch[root][1],root,-1); for(int i=0;i<n;i++) scanf("%d",&a[i]); Build(Key_Value,0,n-1,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]]+1; if(k==t) return r; else if(k<t) return Get_Kth(ch[r][0],k); else return Get_Kth(ch[r][1],k-t);}int ADD(int x){ Splay(tp,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; Push_Up(ch[root][1]); Push_Up(root); Splay(Get_Kth(root,size[root]-1),0);//连接到末尾 Key_Value=tmp; pre[Key_Value]=ch[root][1]; Push_Up(ch[root][1]); Push_Up(root); Splay(Get_Kth(root,1),0);//更新 Splay(Get_Kth(root,k2+2),root); Update_Add(Key_Value,x); Push_Up(ch[root][1]); Push_Up(root); tp=Get_Kth(root,2);}int REVERSE(){ Splay(tp,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; Push_Up(ch[root][1]); Push_Up(root); Splay(Get_Kth(root,size[root]-1),0);//连接到末尾 Key_Value=tmp; pre[Key_Value]=ch[root][1]; Push_Up(ch[root][1]); Push_Up(root); Splay(Get_Kth(root,1),0);//更新 Splay(Get_Kth(root,k1+2),root); Update_Rev(Key_Value); Push_Up(ch[root][1]); Push_Up(root); tp=Get_Kth(root,2);}void INSERT(int x){ Splay(tp,0); int t=size[ch[root][0]]+2; Splay(Get_Kth(root,t),root); New_Node(Key_Value,ch[root][1],x); Push_Up(ch[root][1]); Push_Up(root);}void DELETE(){ Splay(tp,0); int tmp=size[ch[root][0]]+1; Splay(Get_Kth(root,tmp-1),0); Splay(Get_Kth(root,tmp+1),root); s[++tot2]=Key_Value; Key_Value=0; Push_Up(ch[root][1]); Push_Up(root); if(tmp==size[root]) tp=Get_Kth(root,2); else tp=Get_Kth(root,tmp);}int MOVE(int x){ if(x==1) { Splay(tp,0); int t=size[ch[root][0]]+1; t--; if(t==1) t=size[root]-1; tp=Get_Kth(root,t); } else { Splay(tp,0); int t=size[ch[root][0]]+1; t++; if(t==size[root]) t=2; tp=Get_Kth(root,t); }}int query(){ Splay(tp,0); return key[root];}char op[100];int x;int main(){ int kase=0; while(scanf("%d%d%d%d",&n,&q,&k1,&k2)==4) { if(n==0&&q==0&&k1==0&&k2==0) break; printf("Case #%d:\n",++kase); Init(); tp=Get_Kth(root,2); while(q--) { 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 printf("%d\n",query()); } } return 0;}
0 0
- HDU 4453 Looploop(SplayTree)
- hdu-4453-Looploop-splay
- 【HDU】4453 Looploop 【splay】
- HDU 4453 Looploop (Treap)
- hdu 4453 Looploop (伸展树)
- hdu 4453 Looploop(伸展树)
- 【HDU 4453】 Looploop(Splay)
- hdu 4453 Looploop(splay)
- hdu 4453 Looploop 伸展树splay
- HDU 4453 Looploop (双向链表)
- HDU-4453 Looploop(Splay树)
- HDU 4453 Looploop (splay tree)
- hdu 4453 Looploop(Splay或者三个双端队列)
- Hdu 4453 Looploop(环上的Splay操作)
- HDOJ 4453 Looploop Splay
- HDU 3436 Queue-jumpers (Splaytree)
- HDU 1890 Robotic Sort(SplayTree)
- 【splay tree】 HDOJ 4453 Looploop
- 活用UML-软件设计高手(深圳,2014-4-26~27)- 活动报道
- 关于软件测试用例生成技术相关研究总结
- 运算符重载
- loadrunner 监控tomcat的代码
- 警察与小偷的实现之一客户端与服务端通信
- HDU 4453 Looploop(SplayTree)
- Seajs 使用总结
- 深入分析Linux内核源码
- 同一线程多次创建 的 线程资源释放问题在每个线程的一开始,用pthred_detach(pthread_self())来使自己detach掉
- Skynet网络模型
- scala implicit 隐式转换
- js 后缀数组求最大重复子串
- Boost智能指针——shared_ptr
- 苹果为何是Linux的最大竞争对手?