hdu 4453 Looploop(Splay或者三个双端队列)
2013-09-05 01:33
549 查看
题意:有N个数字围成一个圈,有M个操作,操作类型有六种:(1)“add x",从当前指针位置开始的顺时针K2个数加上x。(2)"reverse",翻转,从当前指针指针位置开始的顺时针的K2个数。(3)"insert x",在当前指针位置的顺时候方向插入一个数x。(4)”delete“,删除当前指针所指的数。(5)"move x”,如果x=1,指针逆时针旋转,如果x=2,顺时针旋转。(6)“query",查询指针所指向的数的值。
Splay的作法就不说了。还可以有三个双端队列加两个标记搞定,方法,是第一个双端队列que1维护前K1个数,第二个que2维护第K1+1到第K2个数,第三个que3维护接下的数,标记add,表示que1和que2里的数要加上多少,标记head,表示que1是否被翻转过。
Splay(姿势1):
Spaly(姿势2):
三个双端队列:
Splay的作法就不说了。还可以有三个双端队列加两个标记搞定,方法,是第一个双端队列que1维护前K1个数,第二个que2维护第K1+1到第K2个数,第三个que3维护接下的数,标记add,表示que1和que2里的数要加上多少,标记head,表示que1是否被翻转过。
Splay(姿势1):
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <vector> #include <algorithm> #include <queue> #include <set> #include <map> using namespace std; typedef long long LL; typedef pair<int,int> PII; #define LL(x) (ch[x][0]) #define RR(x) (ch[x][1]) #define Kt (ch[ ch[Rt][1] ][0]) #define MID(a,b) (a+((b-a)>>1)) const int N=1e6+5; int n,m,k1,k2; int a[N/2]; struct SplayTree { int Rt,top; int pre ,sz ,ch [2]; int key ,add ,pos; bool flip ; inline void Link(int x,int y,int f) { pre[x]=y; if(y) ch[y][f]=x; } inline void Rotate(int x,int f) { int y=pre[x],z=pre[y]; PushDown(y); PushDown(x); Link(x,z,RR(z)==y); Link(ch[x][f],y,!f); Link(y,x,f); PushUp(y); } inline void Splay(int x,int goal) { while(pre[x]!=goal) { int y=pre[x],z=pre[y]; int cx=(LL(y)==x),cy=(LL(z)==y); if(z==goal) Rotate(x,cx); else { if(cx==cy) Rotate(y,cy); else Rotate(x,cx); Rotate(x,cy); } } PushUp(x); if(goal==0) Rt=x; } inline void Select(int K,int goal) { int x=Rt; PushDown(x); while(1) { if(sz[LL(x)]>=K) x=LL(x); else if(sz[LL(x)]+1==K) break; else K-=sz[LL(x)]+1,x=RR(x); PushDown(x); } Splay(x,goal); } inline void fun_add(int x,int valu) { add[x]+=valu; key[x]+=valu; } inline void fun_flip(int x) { flip[x]^=1; swap(LL(x),RR(x)); } inline void PushDown(int x) { if(add[x]) { fun_add(LL(x),add[x]); fun_add(RR(x),add[x]); add[x]=0; } if(flip[x]) { fun_flip(LL(x)); fun_flip(RR(x)); flip[x]=0; } } inline void PushUp(int x) { sz[x]=1+sz[LL(x)]+sz[RR(x)]; } inline void Add(int x) { Select(1,0); Select(k2+2,Rt); fun_add(Kt,x); } inline void Reverse() { Select(1,0); Select(k1+2,Rt); fun_flip(Kt); } inline void Insert(int x,int pos) { Select(pos,0); Select(pos+1,Rt); addNode(x,Kt,RR(Rt)); PushUp(RR(Rt)); PushUp(Rt); } inline int Delete(bool top) { int valu; if(top) { Select(1,0); Select(3,Rt); valu=key[Kt]; Kt=0; PushUp(RR(Rt)); PushUp(Rt); } else { int len=sz[Rt]; Select(len-2,0);Select(len,Rt); valu=key[Kt]; Kt=0; PushUp(RR(Rt)); PushUp(Rt); } return valu; } inline void Move(int x) { if(x==1) { int valu=Delete(0); Insert(valu,1); } else { int valu=Delete(1); Insert(valu,sz[Rt]-1); } } inline void Query() { Select(2,0); printf("%d\n",key[Rt]); } // void Debug(){ printf("Rt:%d\n",Rt); Travel(Rt); } // void Travel(int x) // { // if(x==0) return; // // PushDown(x); // Travel(LL(x)); // printf("node:%d,pre:%d,sz:%d,LL:%d,RR:%d,key:%d\n", // x,pre[x],sz[x],LL(x),RR(x),key[x]); // Travel(RR(x)); // } void addNode(int valu,int &x,int f) { x=++top; pre[x]=f; sz[x]=1; LL(x)=RR(x)=0; key[x]=valu; add[x]=flip[x]=0; } void build(int lft,int rht,int &x,int f) { if(lft>rht) return; int mid=MID(lft,rht); addNode(a[mid],x,f); build(lft,mid-1,LL(x),x); build(mid+1,rht,RR(x),x); PushUp(x); } void init() { Rt=top=0; pre[0]=sz[0]=LL(0)=RR(0)=0; addNode(0,Rt,0); addNode(0,RR(Rt),Rt); build(0,n-1,Kt,RR(Rt)); PushUp(RR(Rt)); PushUp(Rt); } }spt; int main() { int t_cnt=0; while(scanf("%d%d%d%d",&n,&m,&k1,&k2)!=EOF) { if(n==0&&m==0&&k1==0&&k2==0) break; for(int i=0;i<n;i++) scanf("%d",&a[i]); spt.init(); printf("Case #%d:\n",++t_cnt); char op[100]; int x; while(m--) { scanf("%s",op); if(op[0]=='a') { scanf("%d",&x); spt.Add(x); } else if(op[0]=='r') spt.Reverse(); else if(op[0]=='i') { scanf("%d",&x); spt.Insert(x,2); } else if(op[0]=='d') spt.Delete(1); else if(op[0]=='m') { scanf("%d",&x); spt.Move(x); } else spt.Query(); } } return 0; }
Spaly(姿势2):
#include <iostream> #include <cstdio> #include <cstring> using namespace std; #define LL(x) (ch[x][0]) #define RR(x) (ch[x][1]) #define Kt (ch[ ch[Rt][1] ][0]) #define MID(a,b) (a+((b-a)>>1)) const int N=1e6+5; int a[N/2]; int n,m,K1,K2,pos; struct SplayTree { int Rt,top; int sz ,pre ,ch [2]; bool flip ; int key ,add ; inline void Link(int x,int y,int f) { pre[x]=y; if(y) ch[y][f]=x; } inline void Rotate(int x,int f) { int y=pre[x],z=pre[y]; PushDown(y); PushDown(x); Link(x,z,RR(z)==y); Link(ch[x][f],y,!f); Link(y,x,f); PushUp(y); } inline void Splay(int x,int goal) { while(pre[x]!=goal) { int y=pre[x],z=pre[y]; int cx=(LL(y)==x),cy=(LL(z)==y); if(z==goal) Rotate(x,cx); else { if(cx==cy) Rotate(y,cy); else Rotate(x,cx); Rotate(x,cy); } } PushUp(x); if(goal==0) Rt=x; } inline void Select(int K,int goal) { int x=Rt; PushDown(x); while(1) { if(sz[LL(x)]>=K) x=LL(x); else if(1+sz[LL(x)]==K) break; else K-=sz[LL(x)]+1,x=RR(x); PushDown(x); } Splay(x,goal); } inline void fun_add(int x,int valu) { key[x]+=valu; add[x]+=valu; } inline void fun_flip(int x) { flip[x]^=1; swap(LL(x),RR(x)); } inline void PushUp(int x) { sz[x]=1+sz[LL(x)]+sz[RR(x)]; } inline void PushDown(int x) { if(add[x]) { fun_add(LL(x),add[x]); fun_add(RR(x),add[x]); add[x]=0; } if(flip[x]) { fun_flip(LL(x)); fun_flip(RR(x)); flip[x]=0; } } inline void Add(int st,int ed,int valu) { Select(st-1,0); Select(ed+1,Rt); fun_add(Kt,valu); } inline void Reverse(int st,int ed) { Select(st-1,0); Select(ed+1,Rt); fun_flip(Kt); } inline void Insert(int pos,int valu) { Select(pos,0); Select(pos+1,Rt); addNode(valu,Kt,RR(Rt)); PushUp(RR(Rt)); PushUp(Rt); } inline void Delete(int pos) { Select(pos-1,0); Select(pos+1,Rt); Kt=0; PushUp(RR(Rt)); PushUp(Rt); } inline void Query(int pos) { Select(pos,0); printf("%d\n",key[Rt]); } inline void Move(int len) { pos-=len; Select(1,0); Select(2+len,Rt); int r1=Kt; Kt=0; PushUp(RR(Rt)); PushUp(Rt); Select(sz[Rt]-1,0); Select(sz[Rt],Rt); Link(r1,RR(Rt),0); PushUp(RR(Rt)); PushUp(Rt); } inline void addNode(int valu,int &x,int f) { x=++top; sz[x]=1; pre[x]=f; LL(x)=RR(x)=0; key[x]=valu; add[x]=flip[x]=0; } void build(int lft,int rht,int &x,int f) { if(lft>rht) return; int mid=MID(lft,rht); addNode(a[mid],x,f); build(lft,mid-1,LL(x),x); build(mid+1,rht,RR(x),x); PushUp(x); } void init() { Rt=top=0; addNode(0,Rt,0); addNode(0,RR(Rt),Rt); build(0,n-1,Kt,RR(Rt)); PushUp(RR(Rt)); PushUp(Rt); } // void Debug(){ printf("Rt:%d\n",Rt); Travel(Rt); } // void Travel(int x) // { // if(x==0) return; // PushDown(x); // Travel(LL(x)); // printf("node:%d,sz:%d,pre:%d,LL:%d,RR:%d,key:%d\n", // x,sz[x],pre[x],LL(x),RR(x),key[x]); // Travel(RR(x)); // } }spt; void deal(int &pos,int len) { if(pos<=1) pos=len-1; if(pos>=len) pos=2; } int main() { freopen("in.txt","r",stdin); int t_cnt=0; while(scanf("%d%d%d%d",&n,&m,&K1,&K2)!=EOF) { if(n==0&&m==0&&K1==0&&K2==0) break; for(int i=0;i<n;i++) scanf("%d",&a[i]); spt.init(); pos=2; printf("Case #%d:\n",++t_cnt); char op[100]; int x; while(m--) { int len=spt.sz[spt.Rt]; scanf("%s",op); if(op[0]=='a') { scanf("%d",&x); if(pos+K2>len) spt.Move(pos+K2-len); spt.Add(pos,pos+K2-1,x); } else if(op[0]=='r') { if(pos+K1>=len) spt.Move(pos+K1-len); spt.Reverse(pos,pos+K1-1); } else if(op[0]=='i') { scanf("%d",&x); spt.Insert(pos,x); } else if(op[0]=='d') { spt.Delete(pos); deal(pos,spt.sz[spt.Rt]); } else if(op[0]=='m') { scanf("%d",&x); if(x==1) pos--; else pos++; deal(pos,len); } else if(op[0]=='q') spt.Query(pos); // spt.Debug(); } } return 0; }
三个双端队列:
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <vector> #include <algorithm> #include <queue> #include <set> #include <map> using namespace std; typedef long long LL; typedef pair<int,int> PII; const int N=1e5+5; int n,m,k1,k2; int a ; struct Looploop { deque<int> que1,que2,que3; int add,head; void init() { add=0; head=1; while(!que1.empty()) que1.pop_back(); while(!que2.empty()) que2.pop_back(); while(!que3.empty()) que3.pop_back(); for(int i=0;i<k1;i++) que1.push_back(a[i]); for(int i=k1;i<k2;i++) que2.push_back(a[i]); for(int i=k2;i<n ;i++) que3.push_back(a[i]); } void Add(int x){ add+=x; } void Reverse() { head=!head; } void Insert(int x) { if(head) { que3.push_back(que1.front()+add); que1.pop_front(); que1.push_front(x-add); } else { que3.push_back(que1.back()+add); que1.pop_back(); que1.push_back(x-add); } Move(1); } void Delete() { if(head) { que1.pop_front(); que1.push_back(que2.front()); } else { que1.pop_back(); que1.push_front(que2.front()); } que2.pop_front(); que2.push_back(que3.front()-add); que3.pop_front(); } void Move(int x) { if(x==2) { if(head) { que3.push_back(que1.front()+add); que1.pop_front(); que2.push_back(que3.front()-add); que3.pop_front(); que1.push_back(que2.front()); que2.pop_front(); } else { que3.push_back(que1.back()+add); que1.pop_back(); que2.push_back(que3.front()-add); que3.pop_front(); que1.push_front(que2.front()); que2.pop_front(); } } else { if(head) { que1.push_front(que3.back()-add); que3.pop_back(); que2.push_front(que1.back()); que1.pop_back(); que3.push_front(que2.back()+add); que2.pop_back(); } else { que1.push_back(que3.back()-add); que3.pop_back(); que2.push_front(que1.front()); que1.pop_front(); que3.push_front(que2.back()+add); que2.pop_back(); } } } void query() { if(head) printf("%d\n",que1.front()+add); else printf("%d\n",que1.back()+add); } void Display() { printf("head:%d,add:%d\n",head,add); printf("que1: "); int len=(int)que1.size(); if(head) { for(int i=0;i<len;i++) printf("%d ",que1[i]+add);puts(""); } else { for(int i=len-1;i>=0;i--) printf("%d ",que1[i]+add);puts(""); } printf("que2: "); len=(int)que2.size(); for(int i=0;i<len;i++) printf("%d ",que2[i]+add);puts(""); printf("que3: "); len=(int)que3.size(); for(int i=0;i<len;i++) printf("%d ",que3[i]);puts(""); } }loop; int main() { int t_cnt=0; while(scanf("%d%d%d%d",&n,&m,&k1,&k2)!=EOF) { if(n==0&&m==0&&k1==0&&k2==0) break; for(int i=0;i<n;i++) scanf("%d",&a[i]); loop.init(); printf("Case #%d:\n",++t_cnt); int tmp; char op[100]; while(m--) { scanf("%s",op); if(op[0]=='a') { scanf("%d",&tmp); loop.Add(tmp); } else if(op[0]=='r') loop.Reverse(); else if(op[0]=='i') { scanf("%d",&tmp); loop.Insert(tmp); } else if(op[0]=='d') loop.Delete(); else if(op[0]=='m') { scanf("%d",&tmp); loop.Move(tmp); } else loop.query(); } } return 0; }
相关文章推荐
- HDU-4453 Looploop(Splay树) 4000
- hdu-4453-Looploop-splay
- hdu 4453 Looploop(splay)
- 【HDU】4453 Looploop 【splay】
- 【HDU 4453】 Looploop(Splay)
- hdu 4453 Looploop 伸展树splay
- hdu4453 Looploop 2012年杭州现场赛 Splay
- hdu 4453 Looploop(splay基本操作)
- Hdu 4453 Looploop(环上的Splay操作)
- hdu 5261 蜀道难(deque 双端队列)
- hdu 5929 Basic Data Structure (双端队列)
- HDU 4286 Data Handler [栈,双端队列]
- (HDU 5929)Basic Data Structure 双端队列+模拟 <2016CCPC东北地区大学生程序设计竞赛 - 重现赛 >
- hdu 5380 Travel with candy(双端队列)
- HDU 5098 Smart Software Installer 双队列拓扑排序或者DAG的最长路
- hdu 5289 ST表+双指针或者优先队列或者multiset
- HDU 4453 Looploop (Treap)
- NYOJ-258/POJ-2559/HDU-1506 Largest Rectangle in a Histogram,最大长方形,dp或者单调队列!
- HDU 4286 Data Handler --双端队列
- LinkedList实现栈、队列或者双端队列分析