bzoj 1251 序列终结者
2015-11-16 10:38
176 查看
狂刷splay中,机房里不时爆出骂爹骂娘的声音。基本算裸题,唯一写错的地方是在find_k的时候要先release。因为子树的大小会变
#include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<cmath> #define md #define ll long long #define inf 1000000000000000LL #define eps 1e-8 #define N 500010 using namespace std; bool rev ; int fa ,ch [2],sz ; ll dt ,mx ,ad ; int root,n; inline bool dir(int x) { return ch[fa[x]][1]==x;} void release(int x) { if (rev[x]) { rev[x]^=1; swap(ch[x][0],ch[x][1]); if (ch[x][0]) rev[ch[x][0]]^=1; if (ch[x][1]) rev[ch[x][1]]^=1; } int l=ch[x][0],r=ch[x][1]; if (ad[x]!=0) { ll d=ad[x]; ad[x]=0; if (l) { dt[l]+=d; mx[l]+=d; ad[l]+=d;} if (r) { dt[r]+=d; mx[r]+=d; ad[r]+=d;} } } void update(int x) { int l=ch[x][0],r=ch[x][1]; sz[x]=sz[l]+sz[r]+1; mx[x]=max(dt[x],max(mx[l],mx[r])); } void rotate(int x) { int y=fa[x],z=fa[y],b=dir(x),c=dir(y),a=ch[x][!b]; if (z) ch[z][c]=x; else root=x; if (a) fa[a]=y; fa[y]=x; fa[x]=z; ch[x][!b]=y; ch[y][b]=a; update(y); update(x); } void splay(int x,int i) { while (fa[x]!=i) { int y=fa[x],z=fa[y]; if (z==i) { release(y); release(x); rotate(x);} else { release(z); release(y); release(x); if (dir(x)==dir(y)) { rotate(y); rotate(x); } else { rotate(x); rotate(x); } } } } int find_k(int x,int k) { release(x); if (sz[ch[x][0]]==k) return x; if (sz[ch[x][0]]>k) return find_k(ch[x][0],k); return find_k(ch[x][1],k-sz[ch[x][0]]-1); } int find_min(int x) { while (ch[x][0]) x=ch[x][0]; return x; } int build(int l,int r,int father) { if (l>r) return 0; int mid=(l+r)>>1; fa[mid]=father; ch[mid][0]=build(l,mid-1,mid); ch[mid][1]=build(mid+1,r,mid); update(mid); return mid; } void ycl() { mx[0]=dt[0]=-inf; root=build(1,n+2,0); } void outit() { for (int i=1;i<=n+2;i++) printf("%d %d %d %d %d %lld %lld %lld %d\n",i,ch[i][0],ch[i][1],fa[i],sz[i],mx[i],dt[i],ad[i],rev[i]); } int main() { int tt,L,R,opt; ll d; scanf("%d%d",&n,&tt); ycl(); //outit(); while (tt--) { scanf("%d",&opt); if (opt==1) { scanf("%d%d%lld",&L,&R,&d); int x=find_k(root,L-1); splay(x,0); int y=find_k(root,R+1); splay(y,x); ad[ch[y][0]]+=d;dt[ch[y][0]]+=d;mx[ch[y][0]]+=d; } else if (opt==2) { scanf("%d%d",&L,&R); int x=find_k(root,L-1); splay(x,0); int y=find_k(root,R+1); splay(y,x); rev[ch[y][0]]^=1; } else { scanf("%d%d",&L,&R); int x=find_k(root,L-1); splay(x,0); int y=find_k(root,R+1); splay(y,x); printf("%lld\n",mx[ch[y][0]]); } //outit(); } return 0; }
相关文章推荐
- bzoj 4152 the camptin (dis[x][y]=min(|x.x-y.x|,|x.y-y.y|),求1,n最短路)
- bzoj 3029 守卫者的挑战
- bzoj 2118 墨墨的等式
- <android5.0>之曲线动画(Curved motion(曲线运动))
- 浅谈虚数i在电路分析中的作用
- 【数据库7】字段相关与联合结果集
- Jenkins入门系列之——02第二章 Jenkins安装与配置
- 简述类目的优缺点,如果覆盖了本类或者父类的方法 ,会出现什么问题
- [Hibernate系列—] 1. 下载与试用Hibernate(MySQL与Oracle 配置)
- Java中String转化为其他类型方法汇总
- 用R做线性回归
- 出圈问题
- Jenkins入门系列之——01第一章 Jenkins是什么?
- bzoj 4010 菜肴制作|拓扑排序|priority_queue|解题思想
- bzoj 1414 对称的正方形
- 网络流刷题列表
- bzoj 2084 反对称子串
- bzoj 3790 神奇项链
- bzoj 3631 松鼠的新家
- bzoj 1064 假面舞会