poj 3468 A Simple Problem with Integers(伸展树)
来源:互联网 发布:access数据库查询 编辑:程序博客网 时间:2024/05/19 13:58
题意:给n个数,有两种操作,一种是查询区间和,另一种是在区间上每一个数加上v。
思路:本来线段树是非常好写的,但是为了学习伸展树练练手,就写了个伸展树。第一次写,代码基本上是抄的cxlove的Orz……http://blog.csdn.net/acm_cxlove/article/details/7815019
代码:
#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<map>#include<queue>#include<set>#include<stack>#include<cmath>#include<vector>#define inf 0x3f3f3f3f#define Inf 0x3FFFFFFFFFFFFFFFLL#define eps 1e-9#define pi acos(-1.0)using namespace std;typedef long long ll;const int maxn=100000+10;int pre[maxn],ch[maxn][2],val[maxn],root,tot;int size[maxn],add[maxn],num[maxn];ll sum[maxn];int n,q;void Newnode(int & rt,int fa,int v){ rt=++tot; pre[rt]=fa; val[rt]=v; sum[rt]=v; add[rt]=0; size[rt]=1; ch[rt][0]=ch[rt][1]=0;}void PushUp(int rt){ size[rt]=size[ch[rt][0]]+size[ch[rt][1]]+1; sum[rt]=sum[ch[rt][0]]+sum[ch[rt][1]]+val[rt];}void PushDown(int rt){ if(add[rt]) { val[rt]+=add[rt]; add[ch[rt][0]]+=add[rt]; add[ch[rt][1]]+=add[rt]; sum[ch[rt][0]]+=(ll)add[rt]*size[ch[rt][0]]; sum[ch[rt][1]]+=(ll)add[rt]*size[ch[rt][1]]; add[rt]=0; }}void Rotate(int x,int kind){ int y=pre[x]; PushDown(x);PushDown(y); ch[y][kind^1]=ch[x][kind]; pre[ch[x][kind]]=y; if(pre[y]) ch[pre[y]][ch[pre[y]][1]==y]=x; pre[x]=pre[y]; ch[x][kind]=y; pre[y]=x; PushUp(y);}void Splay(int rt,int goal){ PushDown(rt); while(pre[rt]!=goal) { if(pre[pre[rt]]==goal) Rotate(rt,ch[pre[rt]][0]==rt); else { int y=pre[rt]; int kind=ch[pre[y]][0]==y; if(ch[y][kind]==rt) { Rotate(rt,kind^1); Rotate(rt,kind); } else { Rotate(y,kind); Rotate(rt,kind); } } } PushUp(rt); if(goal==0) root=rt;}void RotateTo(int k,int goal){ int rt=root; PushDown(rt); while(size[ch[rt][0]]!=k) { if(size[ch[rt][0]]>k) rt=ch[rt][0]; else { k-=(size[ch[rt][0]]+1); rt=ch[rt][1]; } PushDown(rt); } Splay(rt,goal);}ll Query(int l,int r){ RotateTo(l-1,0); RotateTo(r+1,root); return sum[ch[ch[root][1]][0]];}void Update(int l,int r,int v){ RotateTo(l-1,0); RotateTo(r+1,root); int tmp=ch[ch[root][1]][0]; add[tmp]+=v; sum[tmp]+=(ll)size[tmp]*v;}void build(int l,int r,int & rt,int fa){ if(l>r) return ; int m=(l+r)>>1; Newnode(rt,fa,num[m]); build(l,m-1,ch[rt][0],rt); build(m+1,r,ch[rt][1],rt); PushUp(rt);}void Init(){ for(int i=0;i<n;++i) scanf("%d",&num[i]); pre[0]=ch[0][0]=ch[0][1]=size[0]=0; sum[0]=add[0]=0; root=tot=0; Newnode(root,0,-1); Newnode(ch[root][1],root,-1); size[root]=2; build(0,n-1,ch[ch[root][1]][0],ch[root][1]); PushUp(ch[root][1]); PushUp(root);}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int l,r,v; char str[5]; scanf("%d%d",&n,&q); Init(); while(q--) { scanf("%s",str); scanf("%d%d",&l,&r); if(str[0]=='Q') printf("%lld\n",Query(l,r)); else { scanf("%d",&v); Update(l,r,v); } } return 0;}
0 0
- poj 3468 A Simple Problem with Integers(伸展树)
- POJ 3468 A Simple Problem with Integers (伸展树区间更新求和操作 , 模板)
- POJ 3468 A Simple Problem with Integers 伸展树splay 区间更新
- kyeremal-poj3468-A simple Problem with Integers-伸展树
- POJ A Simple Problem with Integers (Splay 伸展树 入门)
- POJ 3468 A Simple Problem With Integers
- poj 3468 A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers
- POJ 3468 A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers
- POJ-3468-A Simple Problem with Integers
- POJ 3468 A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers
- POJ 3468 - A Simple Problem with Integers
- poj 3468 A Simple Problem with Integers
- Fix the computers ——(并查集) 结题报告
- java的操作技术!
- commands commence before first target makefile
- 第五章 网络层
- 深度解析Java内存的原型
- poj 3468 A Simple Problem with Integers(伸展树)
- 二叉查找树
- Java程序员应该了解的10个面向对象设计原则
- 解题报告之——大牛也会不A题
- PHP定时执行计划任务
- Ext文件上传
- java Streaming!
- 组合选择 的应用
- uva 11578 Situp Benches (DP)求完dp之后求路径