hdu4453 伸展树
来源:互联网 发布:中文作曲软件 编辑:程序博客网 时间:2024/05/16 19:26
第一道伸展树题目 7K的代码连写带调耗了将近一天时间 各种细节错误 AC的时候有种解脱的感觉 终于不用睡不着觉了 数据结构的题目就是坑
ACcode:
#include<set>#include<map>#include<cmath>#include<vector>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;typedef long long LL;const int NS=200100;const double eps=1e-8;int n,m,k1,k2,pos,cnt;int arr[NS];int deg=0;#define debug if(deg)#define debuv debug{spt.traval(spt.root);}struct splaytree{ #define ls(cur) ch[cur][0] #define rs(cur) ch[cur][1] int root; int sz[NS],fp[NS]; int key[NS],val[NS]; int ch[NS][2],pre[NS]; void Pushdown(int x) { if (!val[x] && !fp[x]) return ; int l=ls(x),r=rs(x); if (l>0) key[l]+=val[x],val[l]+=val[x],fp[l]^=fp[x]; if (r>0) key[r]+=val[x],val[r]+=val[x],fp[r]^=fp[x]; if (fp[x]) swap(ls(x),rs(x)); val[x]=fp[x]=0; } void Pushup(int x) { sz[x]=sz[ls(x)]+sz[rs(x)]+1; } void Rotate(int x,int dir) //0右旋 1左旋 { int y=pre[x],z=pre[y]; Pushdown(y),Pushdown(x); pre[x]=z,pre[y]=x; if (z>0) if (ch[z][0]==y) ch[z][0]=x; else ch[z][1]=x; z=ch[y][dir]=ch[x][!dir]; if (z>0) pre[z]=y; ch[x][!dir]=y; if (y==root) root=x; Pushup(y); } void splay(int x,int fa) { for (;pre[x]!=fa;) { int y=pre[x],z=pre[y]; if (z==fa) if (ch[y][0]==x) Rotate(x,0); else Rotate(x,1); else if (ch[z][0]==y) if (ch[y][0]==x) Rotate(y,0),Rotate(x,0); else Rotate(x,1),Rotate(x,0); else if (ch[y][0]==x) Rotate(x,0),Rotate(x,1); else Rotate(y,1),Rotate(x,1); } Pushup(x); } int findkth(int x,int k) { Pushdown(x); for(int i=sz[ls(x)];i+1!=k;i=sz[ls(x)]) { if (i>=k) x=ls(x); else k-=i+1,x=rs(x); Pushdown(x); } return x; } int newnode(int x,int v) { key[cnt]=v,sz[cnt]=1; val[cnt]=fp[cnt]=0; ls(cnt)=rs(cnt)=0; pre[cnt]=x; return cnt++; } void change() { if (sz[root]<=2) pos=1; else if (pos>=sz[root]) pos=2; else if (pos<2) pos=sz[root]-1; } void init(int n) { for (int i=0;i<3;i++) pre[i]=val[i]=key[i]=sz[i]=fp[i]=ls(i)=rs(i)=0; pos=root=2,cnt=n+4; int fa=0; for (int i=2;i<n+3;i++) { val[i]=fp[i]=ls(i)=0; pre[i]=fa; fa=i; key[i]=arr[i]; sz[i]=cnt-i; rs(i)=i+1; } rs(fa)=sz[1]=1,pre[1]=fa; } void add(int st,int v) { int tot=sz[root]-2; if (tot<=0) return ; val[root]+=k2/tot*v; key[root]+=k2/tot*v; int num=k2%tot; if (!num) return ; tot=sz[root]; if (st>2) { splay(findkth(root,1),0); splay(findkth(root,st),root); int trt=ls(rs(root)); pre[trt]=ls(rs(root))=0; Pushup(rs(root)); Pushup(root); splay(findkth(root,tot-st+2),0); splay(findkth(root,tot-st+1),root); rs(ls(root))=trt; pre[trt]=ls(root); Pushup(ls(root)); Pushup(root); pos=2; } splay(findkth(root,1),0); splay(findkth(rs(root),num+1),root); val[ls(rs(root))]+=v; key[ls(rs(root))]+=v; } void reverse(int st) { int tot=sz[root]; if (tot<=2) return ; if (st>2) { splay(findkth(root,1),0); splay(findkth(root,st),root); int trt=ls(rs(root)); pre[trt]=ls(rs(root))=0; Pushup(rs(root)); Pushup(root); splay(findkth(root,tot-st+2),0); splay(findkth(root,tot-st+1),root); rs(ls(root))=trt; pre[trt]=ls(root); Pushup(ls(root)); Pushup(root); pos=2; } splay(findkth(root,1),0); splay(findkth(rs(root),k1+1),root); if (ls(rs(root))) fp[ls(rs(root))]^=1; } void insert(int st,int v) { splay(findkth(root,st),0); splay(findkth(rs(root),1),root); ls(rs(root))=newnode(rs(root),v); Pushup(rs(root)),Pushup(root); change(); } void Delete(int st) { splay(findkth(root,st-1),0); splay(findkth(rs(root),2),root); ls(rs(root))=0; Pushup(rs(root)),Pushup(root); change(); } void move(int x) { pos+= x==1?-1:1; change(); } int query(int st) { splay(findkth(root,st),0); return key[root]; } void traval(int x) { if (!deg) return ; printf("rt=%d cur=%d\n",root,key[x]); visit(x); } void visit(int x) { Pushdown(x); int l=ch[x][0],r=ch[x][1]; if (l>0) visit(l); printf("pos=%d fa=%d key=%d val=%d fp=%d sz=%d l=%d r=%d\n", x,pre[x],key[x],val[x],fp[x],sz[x],key[ls(x)],key[rs(x)]); if (r>0) visit(r); Pushup(x); }}spt;int main(){ int cas=0; while (~scanf("%d %d %d %d",&n,&m,&k1,&k2)) { if (n+m+k1+k2==0) break; printf("Case #%d:\n",++cas); for (int i=3;i<n+3;i++) scanf("%d",&arr[i]); arr[1]=arr[2]=0; spt.init(n); char op[10]; for (int x;m--;) { scanf("%s",op); if (op[0]=='a') { scanf("%d",&x); spt.add(pos,x); }else if (op[0]=='r') { spt.reverse(pos); }else if (op[0]=='i') { scanf("%d",&x); spt.insert(pos,x); }else if (op[0]=='d') { spt.Delete(pos); }else if (op[0]=='m') { scanf("%d",&x); spt.move(x); }else if (op[0]=='q') { printf("%d\n",spt.query(pos)); } } } return 0;}
- hdu4453 伸展树
- hdu4453 伸展树基本题
- 伸展树hdu4453(good)
- HDU4453(伸展树模板题)
- hdu4453
- 伸展树:双层伸展
- 伸展树
- 伸展树
- 伸展树
- 伸展树
- 伸展树
- 伸展树
- 伸展树
- 伸展树
- 伸展树
- 伸展树
- 伸展树
- 伸展树
- 调试时注意IE!
- hibernate树形结构
- struts2接收参数的几种形式
- LoaderContext究竟是什么?
- AS3嵌入字体
- hdu4453 伸展树
- 高性能 Windows Socket 组件 HP-Socket v3.0.1 正式发布
- 高性能 Windows Socket 组件 HP-Socket v3.0.1 正式发布
- oracle ITL(事务槽)的理解
- Latex两大命令
- SQL 非主键字段设置为值唯一
- [android] Proguard代码混淆器如何排除指定的类或子类
- Some design patterns were used in the projects
- 那些所谓的“高手”逼着我这么干