poj 3580 splay
来源:互联网 发布:新西兰旅游 知乎 编辑:程序博客网 时间:2024/06/07 17:53
这题没啥好说的。。。就是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]);} }}
0 0
- Splay-tree poj 3580
- poj 3580 splay tree
- splay POJ 3580SuperMemo
- POJ 3580 SuperMemo(Splay)
- POJ 3580 SuperMemo(Splay)
- poj 3580 SuperMemo(Splay)
- poj-3580-SuperMemo-splay
- 【POJ】3580 SuperMemo 【splay】
- POJ 3580 splay
- POJ 3580 SuperMemo Splay
- POJ 3580 Splay
- POJ 3580 SPLAY树
- poj 3580 splay
- POJ 3580 SuperMemo [Splay]
- POJ 3580 splay
- poj 3580(Splay)
- POJ 3580 SuperMemo (Splay tree)
- POJ 3580 SuperMemo (SPLAY TREE)
- 【因子算法】——求一个数的因子、质因子、求两个数的公因子
- 03 crawler
- Python基础
- 如何用tomcat配置虚拟目录,方法要详细明了
- Hibernate懒加载
- poj 3580 splay
- JAVA实现链表中倒数第K个节点问题(《剑指offer》)
- 《php和mysql web开发》笔记——第10章 使用MySQL数据库
- 函数冗余参数
- Non-negative Partial Sums(单调队列,好题)
- Bundle Adjustment 光束法平差详解
- Node.js第三方库之request
- ocp-34
- ZOJ 3829 Known Notation