【splay】【bzoj 1895】: Pku3580 supermemo
2014-11-25 20:21
519 查看
http://www.lydsy.com/JudgeOnline/problem.php?id=1895
终于找到比较像样的模板题了
Orz 策爷单旋3s+ rank 3
我太弱双选无论怎么优化常数6s+
求神犇指导蒟蒻如何优化常数。。。。
难道写个struct会快。?
6540ms:
改了一个小时的struct(今晚没事干么)貌似姿势还有点问题
删掉了回收功能,但代码复杂度增加了不少
3880ms
Updated:Dec.5
成功借鉴了CLJ的模板超越了jcvb!!!
rank 3!!!!!
3456ms
这个好写多了,不过指针版太不熟悉,不容易调试
和Trie的模板趋于一致了
终于找到比较像样的模板题了
Orz 策爷单旋3s+ rank 3
我太弱双选无论怎么优化常数6s+
求神犇指导蒟蒻如何优化常数。。。。
难道写个struct会快。?
6540ms:
//#define _TEST _TEST #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <cmath> #include <algorithm> using namespace std; /************************************************ Code By willinglive Blog:http://willinglive.cf ************************************************/ #define rep(i,l,r) for(int i=l,___t=(r);i<=___t;i++) #define per(i,r,l) for(int i=r,___t=(l);i>=___t;i--) #define MS(arr,x) memset(arr,x,sizeof(arr)) #define LL long long #define INE(i,u,e) for(int i=head[u];~i;i=e[i].next) inline const int read() { int r=0,k=1;char c=getchar(); for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1; for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0'; return k*r; } ///////////////////////////////////////////////// const int N=200005; int n,m; int a ,cnt; int root,fa ,c [2],sz ,id ; int mi ,w ; int add ;bool rev ; int rec ; ///////////////////////////////////////////////// inline int min(int a,int b){return a<b?a:b;} #define LS c[o][0] #define RS c[o][1] inline void pushup(int o) { sz[o]=sz[LS]+sz[RS]+1; mi[o]=w[o]; if(LS) mi[o]=min(mi[o],mi[LS]); if(RS) mi[o]=min(mi[o],mi[RS]); } inline void modify(int o,int x) { if(!o)return; w[o]+=x;mi[o]+=x;add[o]+=x; } inline void flip(int o) { if(!o)return; rev[o]^=1; swap(LS,RS); } inline void pushdown(int o) { int tmp; if(tmp=add[o]) { int l=LS,r=RS; modify(LS,tmp); modify(RS,tmp); add[o]=0; } if(rev[o]) { flip(LS); flip(RS); rev[o]=0; } } void build(int l,int r,int o) { int now=id[l],last=id[o]; w[o]=mi[o]=a[o]; if(l==r) { sz[now]=1; w[now]=mi[now]=a[l]; add[now]=rev[now]=0; return; } RS=id[o+1+r>>1], fa[RS]=id[o]; if(l^o) LS=id[l+o-1>>1], fa[LS]=id[o]; if(l^o) build(l,o-1,l+o-1>>1); build(o+1,r,o+1+r>>1); pushup(o); } inline void reclaim(int o) { if(!o) return; fa[o]=LS=RS=sz[o]=mi[o]=w[o]=add[o]=rev[o]=0; rec[++rec[0]]=o; } inline int newnode() { if(rec[0]) return rec[rec[0]--]; else return ++cnt; } int find(int o,int k) { while(1) { pushdown(o); if(sz[LS]+1==k) return o; if(k<=sz[LS]) o=LS; else k-=sz[LS]+1,o=RS; } } inline void rot(int x,int &k) { int y=fa[x],z=fa[y]; bool f=*c[y]!=x; if(y==k)k=x; else c[z][*c[z]!=y]=x; int &t=c[x][!f]; fa[x]=z; fa[y]=x; fa[t]=y; c[y][f]=t; t=y; pushup(y); } void splay(int x,int &k=root) { while(x^k) { int y=fa[x],z=fa[y]; if(y^k) { if(*c[y]==x^*c[z]==y) rot(x,k); else rot(y,k); }rot(x,k); } } void modify() { int l=read(),r=read(),x=read(); r+=2; splay(l=find(root,l)); splay(r=find(root,r),c[root][1]); int o=c[r][0]; add[o]+=x; w[o]+=x; mi[o]+=x; } void del() { int x=read(),y=x,o; splay(x=find(root,x)); splay(y=find(root,y+2),c[root][1]); o=c[y][0]; reclaim(o); c[y][0]=0; pushup(y); pushup(x); } void insert() { int pos=read()+1,x=read(),y=pos+1; splay(pos=find(root,pos)); splay(y=find(root,y),c[root][1]); int &o=c[y][0]=newnode(); fa[o]=y;sz[o]=1;LS=RS=0; w[o]=mi[o]=x; add[o]=rev[o]=0; pushup(y); pushup(root); } void getmin() { int l=read(),r=read(); r+=2; splay(l=find(root,l)); splay(r=find(root,r),c[root][1]); printf("%d\n",mi[c[r][0]]); } void reverse() { int l=read(),r=read(); r+=2; splay(l=find(root,l)); splay(r=find(root,r),c[root][1]); flip(c[r][0]); } void revolve() { int l=read(),r=read(),k=read(); l++; r++; k%=(r-l+1); if(!k) return; int x=r-k,y=r+1; splay(x=find(root,x)); splay(y=find(root,y),c[root][1]); int tmp=c[y][0]; c[y][0]=0; pushup(y); pushup(x); x=l-1; y=l; splay(x=find(root,x)); splay(y=find(root,y),c[root][1]); c[y][0]=tmp; fa[tmp]=y; pushup(y); pushup(x); } ///////////////////////////////////////////////// void input() { n=read(); rep(i,1,n) a[i+1]=read(); n+=2; cnt=n; a[1]=a =0x3fffffff; rep(i,1,n) id[i]=i; } void solve() { char op[10]; build(1,n,root=n+1>>1); m=read(); while(m--) { scanf("%s",op); if(op[0]=='A') modify(); else if(op[0]=='D') del(); else if(op[0]=='I') insert(); else if(op[0]=='M') getmin(); else if(op[3]=='E') reverse(); else revolve(); } } ///////////////////////////////////////////////// int main() { #ifndef _TEST freopen("std.in","r",stdin); freopen("std.out","w",stdout); #endif input(),solve(); return 0; }
改了一个小时的struct(今晚没事干么)貌似姿势还有点问题
删掉了回收功能,但代码复杂度增加了不少
3880ms
//#define _TEST _TEST #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <cmath> #include <algorithm> using namespace std; /************************************************ Code By willinglive Blog:http://willinglive.cf ************************************************/ #define rep(i,l,r) for(int i=l,___t=(r);i<=___t;i++) #define per(i,r,l) for(int i=r,___t=(l);i>=___t;i--) #define MS(arr,x) memset(arr,x,sizeof(arr)) #define LL long long #define INE(i,u,e) for(int i=head[u];~i;i=e[i].next) inline const int read() { int r=0,k=1;char c=getchar(); for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1; for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0'; return k*r; } ///////////////////////////////////////////////// const int N=200005; int n,m; int a ,cnt; int root,id ; int rec ; struct tree{ int o,fa,c[2],sz,mi,w,add;bool rev; inline void pushup(); inline void modify(int x); inline void flip(); inline void pushdown(); void build(int l,int r,int o); }T ; ///////////////////////////////////////////////// inline int min(int a,int b){return a<b?a:b;} #define LS c[0] #define RS c[1] inline void tree::pushup() { sz=T[LS].sz+T[RS].sz+1; mi=w; if(LS) mi=min(mi,T[LS].mi); if(RS) mi=min(mi,T[RS].mi); } inline void tree::modify(int x) { if(!this)return; w+=x;mi+=x;add+=x; } inline void tree::flip() { if(!this)return; rev^=1; swap(LS,RS); } inline void tree::pushdown() { int tmp; if(tmp=add) { int l=LS,r=RS; T[LS].modify(tmp); T[RS].modify(tmp); add=0; } if(rev) { T[LS].flip(); T[RS].flip(); rev=0; } } void tree::build(int l,int r,int o) { int now=id[l],last=id[o]; w=mi=a[o]; if(l==r) { T[now].o=o; T[now].sz=1; T[now].w=T[now].mi=a[l]; T[now].add=T[now].rev=0; return; } RS=id[o+1+r>>1], T[RS].fa=id[o]; if(l^o) LS=id[l+o-1>>1], T[LS].fa=id[o]; if(l^o) T[LS].build(l,o-1,l+o-1>>1); T[RS].build(o+1,r,o+1+r>>1); T[o].pushup(); } int find(int o,int k) { while(1) { T[o].pushdown(); if(T[T[o].LS].sz+1==k) return o; if(k<=T[T[o].LS].sz) o=T[o].LS; else k-=T[T[o].LS].sz+1,o=T[o].RS; } } inline void rot(int x,int &k) { int y=T[x].fa,z=T[y].fa; bool f=*T[y].c!=x; if(y==k)k=x; else T[z].c[*T[z].c!=y]=x; int &t=T[x].c[!f]; T[x].fa=z; T[y].fa=x; T[t].fa=y; T[y].c[f]=t; t=y; T[y].pushup(); } void splay(int x,int &k=root) { while(x^k) { int y=T[x].fa,z=T[y].fa; if(y^k) { if(*T[y].c==x^*T[z].c==y) rot(x,k); else rot(y,k); }rot(x,k); } } void modify() { int l=read(),r=read(),x=read(); r+=2; splay(l=find(root,l)); splay(r=find(root,r),T[root].RS); int o=T[r].LS; T[o].modify(x); } void del() { int x=read(),y=x,o; splay(x=find(root,x)); splay(y=find(root,y+2),T[root].RS); o=T[y].LS; T[y].LS=0; T[y].pushup(); T[x].pushup(); } void insert() { int pos=read()+1,x=read(),y=pos+1; splay(pos=find(root,pos)); splay(y=find(root,y),T[root].RS); int &o=T[y].LS=++cnt; T[o].o=o; T[o].fa=y; T[o].sz=1; T[o].LS=T[o].RS=0; T[o].w=T[o].mi=x; T[o].add=T[o].rev=0; T[y].pushup(); T[root].pushup(); } void getmin() { int l=read(),r=read(); r+=2; splay(l=find(root,l)); splay(r=find(root,r),T[root].RS); printf("%d\n",T[T[r].LS].mi); } void reverse() { int l=read(),r=read(); r+=2; splay(l=find(root,l)); splay(r=find(root,r),T[root].RS); T[T[r].LS].flip(); } void revolve() { int l=read(),r=read(),k=read(); l++; r++; k%=(r-l+1); if(!k) return; int x=r-k,y=r+1; splay(x=find(root,x)); splay(y=find(root,y),T[root].RS); int tmp=T[y].LS; T[y].LS=0; T[y].pushup(); T[x].pushup(); x=l-1; y=l; splay(x=find(root,x)); splay(y=find(root,y),T[root].RS); T[y].LS=tmp; T[tmp].fa=y; T[y].pushup(); T[x].pushup(); } ///////////////////////////////////////////////// void input() { n=read(); rep(i,1,n) a[i+1]=read(); n+=2; cnt=n; a[1]=a =0x3fffffff; rep(i,1,n) id[i]=i; } void solve() { char op[10]; root=n+1>>1; T[root].build(1,n,root=n+1>>1); m=read(); while(m--) { scanf("%s",op); if(op[0]=='A') modify(); else if(op[0]=='D') del(); else if(op[0]=='I') insert(); else if(op[0]=='M') getmin(); else if(op[3]=='E') reverse(); else revolve(); } } ///////////////////////////////////////////////// int main() { #ifndef _TEST freopen("std.in","r",stdin); freopen("std.out","w",stdout); #endif input(),solve(); return 0; }
Updated:Dec.5
成功借鉴了CLJ的模板超越了jcvb!!!
rank 3!!!!!
3456ms
这个好写多了,不过指针版太不熟悉,不容易调试
和Trie的模板趋于一致了
//#define _TEST _TEST #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <cmath> #include <algorithm> using namespace std; /************************************************ Code By willinglive Blog:http://willinglive.cf ************************************************/ #define rep(i,l,r) for(int i=l,___t=(r);i<=___t;i++) #define per(i,r,l) for(int i=r,___t=(l);i>=___t;i--) #define MS(arr,x) memset(arr,x,sizeof(arr)) #define LL long long #define INE(i,u,e) for(int i=head[u];~i;i=e[i].next) inline const int read() {int r=0,k=1;char c=getchar();for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1; for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';return k*r;} ///////////////////////////////////////////////// const int N=200005; const int inf=0x3fffffff; #define LS c[0] #define RS c[1] int n,a ,cnt; struct node{ node *c[2],*fa; int sz; int w,mi; int add; bool rev; bool d(){return this==fa->c[1];} void setc(node *ch,int x){c[x]=ch;ch->fa=this;} void Add(int x){w+=x; mi+=x; add+=x;} void Flip(){rev^=1;swap(LS,RS);} void pushup(); void pushdown(); void init(); void build(int o,int l,int r); }*root,*null,T ; int cntNode; ///////////////////////////////////////////////// inline void pushrange(){root->RS->pushup();root->pushup();} void node::pushup() { sz=1; if(LS!=null) sz+=LS->sz; if(RS!=null) sz+=RS->sz; mi=w; if(LS!=null&&mi>LS->mi) mi=LS->mi; if(RS!=null&&mi>RS->mi) mi=RS->mi; } void node::pushdown() { if(add) { if(LS!=null) LS->Add(add); if(RS!=null) RS->Add(add); add=0; } if(rev) { if(LS!=null) LS->Flip(); if(RS!=null) RS->Flip(); rev=0; } } node* NewNode() { T[cntNode].init(); return &T[cntNode++]; } void node::build(int l,int r,int o) { w=mi=a[o]; if(l==r) { sz=1; w=mi=a[o]; add=rev=0; return; } RS=NewNode(), RS->fa=this; if(l^o) LS=NewNode(), LS->fa=this; if(l^o) LS->build(l,o-1,l+o-1>>1); RS->build(o+1,r,o+1+r>>1); pushup(); } void node::init() { c[0]=c[1]=fa=null; sz=1; w=mi=0; add=rev=0; } void rot(node *o) { node *f=o->fa; bool d=o->d(); f->fa->setc(o,f->d()); f->setc(o->c[!d],d); o->setc(f,!d); f->pushup(); } void splay(node *o,node *k=null) { while(o->fa!=k) { if(o->fa->fa==k) rot(o); else o->d()==o->fa->d()?(rot(o->fa),rot(o)):(rot(o),rot(o)); } o->pushup(); if(o->fa==null) root=o; } node* find(int k) { int sz; for(node* o=root;;) { o->pushdown(); sz=o->LS->sz; if(k==sz+1) return o; o=o->c[k>sz]; if(k>sz) k-=sz+1; } } node* getrange(int l,int r) { l--;r++; splay(find(l)); splay(find(r),root); return root->RS->LS; } void add() { int l=read(),r=read(),x=read(); l++;r++; node *o=getrange(l,r); o->Add(x); } void del() { int x=read(),y=x; x++; y++; node *o=getrange(x,x); root->RS->LS=o=null; pushrange(); } void insert() { int pos=read()+1,x=read(),y=pos+1; node *o=getrange(pos+1,pos); o=NewNode(); o->Add(x); root->RS->setc(o,0); pushrange(); } void getmin() { int l=read(),r=read(); l++;r++; node* o=getrange(l,r); printf("%d\n",o->mi); } void reverse() { int l=read(),r=read(); l++;r++; node *o=getrange(l,r); o->Flip(); } void revolve() { int l=read(),r=read(),k=read(); l++;r++; k%=(r-l+1); if(!k) return; node *tmp=getrange(r-k+1,r); root->RS->LS=null; pushrange(); node *o=getrange(l,l-1); root->RS->setc(tmp,0); pushrange(); } ///////////////////////////////////////////////// void input() { n=read(); rep(i,1,n) a[i+1]=read(); n+=2; cnt=n; a[1]=a =inf; } void solve() { char op[10]; null=NewNode(); null->sz=0; root=NewNode(); root->build(1,n,n+1>>1); for(int m=read();m--;) { scanf("%s",op); if(op[0]=='A') add(); else if(op[0]=='D') del(); else if(op[0]=='I') insert(); else if(op[0]=='M') getmin(); else if(op[3]=='E') reverse(); else revolve(); } } ///////////////////////////////////////////////// int main() { #ifndef _TEST freopen("std.in","r",stdin); freopen("std.out","w",stdout); #endif input(),solve(); return 0; }
相关文章推荐
- bzoj 1895: Pku3580 supermemo (splay)
- bzoj1895 Pku3580 supermemo(splay)
- [BZOJ 1895]Pku3580 supermemo:Splay
- [BZOJ1895]Pku3580 supermemo(splay)
- BZOJ_1895_Pku3580 supermemo_Splay
- 【bzoj1895】Pku3580 supermemo Splay
- 【BZOJ1895】Pku3580 supermemo Splay
- 【bzoj1895】Pku3580 supermemo
- BZOJ 1895 & POJ 3580 supermemo (splay)
- BZOJ1895: Pku3580 supermemo Splay
- BZOJ 1895 & POJ 3580 supermemo [SPLAY]【数据结构】
- [bzoj1895][Pku3580]supermemo_非旋转Treap
- bzoj1895: Pku3580 supermemo
- bzoj1895: Pku3580 supermemo
- bzoj1895 Pku3580 supermemo splay
- Splay伸展树学习小记 Poj 3580 SuperMemo
- 【POJ】3580 SuperMemo 【splay】
- POJ 3580 SuperMemo(Splay模板)
- POJ 3580 SuperMemo (Splay)
- POJ 3580(SuperMemo-Splay区间加)[template:Splay V2]