poj 3580 splay
2015-10-02 16:23
281 查看
这题没啥好说的。。。就是splay裸题。。然而我的splay的常数大得要死。弄了好久才过了。。。。
注意打标记的写法能有效减少常数。
然后还是数组流好了。。。妈蛋开结构体太蛋疼了。。。。不过结构体合并答案的时候是可以带来方便的,因此我们对于贮存答案的数组还是弄个结构体比较好,比如该死的最大连续子段和。。。。
代码:
注意打标记的写法能有效减少常数。
然后还是数组流好了。。。妈蛋开结构体太蛋疼了。。。。不过结构体合并答案的时候是可以带来方便的,因此我们对于贮存答案的数组还是弄个结构体比较好,比如该死的最大连续子段和。。。。
代码:
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> #include<string> #define rep(i_,a,b) for(int i_=(a);i_<=(b);i_++) using namespace std; const int maxn=201200; const int inf=2147483647; int fa[maxn],c[maxn][2],siz[maxn],ans[maxn],mins[maxn],mark[maxn],key[maxn],sta[maxn]; bool rev[maxn]; int n,m,root,tot; inline void release(int x){ if (x==0) return; if (rev[x]){ swap(c[x][0],c[x][1]); if (c[x][0]) rev[c[x][0]]=!rev[c[x][0]]; if (c[x][1]) rev[c[x][1]]=!rev[c[x][1]]; rev[x]=false; } if (mark[x]!=0){ if (c[x][0]) { mark[c[x][0]]+=mark[x]; key[c[x][0]]+=mark[x]; mins[c[x][0]]+=mark[x]; } if (c[x][1]) { mark[c[x][1]]+=mark[x]; key[c[x][1]]+=mark[x]; mins[c[x][1]]+=mark[x]; } mark[x]=0; } } inline void updata(int x){ if (x==0) return; release(x); siz[x]=siz[c[x][0]]+siz[c[x][1]]+1; mins[x]=key[x]; if (c[x][0]) mins[x]=min(mins[x],mins[c[x][0]]); if (c[x][1]) mins[x]=min(mins[x],mins[c[x][1]]); } void link(int x,int y,int der){ if (x!=0) c[x][der]=y; if (y!=0) fa[y]=x; updata(x); } void cut(int x,int y,int der){ updata(x); if (x!=0) c[x][der]=0; if (y!=0) fa[y]=0; updata(x); } inline void rorate(int x){ if (fa[x]==0) return ; release(fa[x]); release(x); int t=fa[x],t1=fa[fa[x]]; int p=(c[t][1]==x); int p1=(c[fa[t]][1]==t); link(t1,x,p1); link(t,c[x][!p],p); link(x,t,!p); updata(t); } inline void splay(int x,int y){ while (fa[x]!=y){ rorate(x); } updata(x); if (y==0) root=x; else updata(y); } int getrank(int x,int k){ int i=x; int j=k; while (true){ release(i); if (j==siz[c[i][0]]+1) return i; if (siz[c[i][0]]+1<j) { j-=(siz[c[i][0]]+1); i=c[i][1]; } else{ i=c[i][0]; } } } inline void getlr(int l,int r){ int lx=getrank(root,l);int rx=getrank(root,r); splay(lx,0); splay(rx,lx); } int bt(int ff,int l,int r){ if (l>r) return 0; if (l==r){ siz[l]=1; fa[l]=ff; updata(l); return l; } int mid=(l+r)/2; fa[mid]=ff; c[mid][0]=bt(mid,l,mid-1); c[mid][1]=bt(mid,mid+1,r); updata(mid); return mid; } string str; char ss[10]; int main(){ scanf("%d",&n); memset(rev,0,sizeof(rev)); rep(i,1,n){ scanf("%d",&key[i+1]); } key[1]=inf; key[n+2]=inf; tot=n+2; root=bt(0,1,n+2); scanf("%d",&m); while (m--) { scanf("%s",ss); str=string(ss); if ( str == "ADD" ) { int l , r , d; scanf( "%d%d%d" , &l , &r , &d ); getlr(l,r+2); int t=c[c[root][1]][0]; mark[t]+=d; key[t]+=d; mins[t]+=d; } if ( str == "REVERSE" ) { int l , r; scanf( "%d%d" , &l , &r ); getlr(l,r+2); int t=c[c[root][1]][0]; rev[t]=!rev[t]; } if ( str == "REVOLVE" ) { int l , r , k; scanf( "%d%d%d" , &l , &r , &k ); int w=r-l+1; k=((k%w)+w)%w; if (k==0)continue; getlr(r-k+1,r+2); int t=c[c[root][1]][0]; cut(c[root][1],t,0); getlr(l,l+1); link(c[root][1],t,0); } if ( str == "INSERT" ) { int x,p;scanf("%d%d",&x,&p); getlr(x+1,x+2); tot++; key[tot]=p; mins[tot]=p; siz[tot]=1; int t=c[root][1]; link(t,tot,0); } if ( str == "DELETE" ) { int x,t; scanf("%d",&x); getlr(x,x+2); t=c[root][1]; c[t][0]=0; updata(t); updata(root); } if ( str == "MIN" ) { int l,r;scanf("%d%d",&l,&r); getlr(l,r+2); int t=c[c[root][1]][0]; updata(t); printf("%d\n",mins[t]); } } }
相关文章推荐
- 《php和mysql web开发》笔记——第10章 使用MySQL数据库
- jackson 解析结合类(需要传入Class, 和 Class.Class, 回调方法是List<Class>)
- hdu 4813(2013长春现场赛A题)
- Hibernate懒加载
- Python基础
- 03 crawler
- ocp-33
- [LeetCode][JavaScript]Reverse Linked List II
- 栈——括号匹配
- ocp-32
- HDU 2100 模拟
- leetcode 288: Unique Word Abbreviation
- Add Two Numbers - leetcode002
- 应用服务器性能优化
- ios动画
- GO RPC
- 零基础学python-19.8 生成器表达式:当迭代器遇上列表解析
- ocp-31
- mac Xcode/iOS license
- 【kmp字符串匹配】hdu 1686 Oulipo