POJ-3468-A Simple Problem with Integers(区间更新,求和)-splay或线段树
区间更新求和
主要用来练习splay树区间更新问题
//splay树的题解
- // File Name: 3468-splay.cpp
- // Author: Zlbing
- // Created Time: 2013年08月09日 星期五 16时30分32秒
- #include<iostream>
- #include<string>
- #include<algorithm>
- #include<cstdlib>
- #include<cstdio>
- #include<set>
- #include<map>
- #include<vector>
- #include<cstring>
- #include<stack>
- #include<cmath>
- #include<queue>
- using namespace std;
- #define CL(x,v); memset(x,v,sizeof(x));
- #define INF 0x3f3f3f3f
- #define LL long long
- #define REP(i,r,n) for(int i=r;i<=n;i++)
- #define RREP(i,n,r) for(int i=n;i>=r;i--)
- #define L ch[x][0]
- #define R ch[x][1]
- #define KT (ch[ch[rt][1]][0])
- const int MAXN=2e5+;
- struct SplayTree{
- int ch[MAXN][];
- int pre[MAXN],sz[MAXN],val[MAXN];
- int rt,top;
- void Rotate(int x,int f)
- {
- int y=pre[x];
- down(y);down(x);
- ch[y][!f]=ch[x][f];
- pre[ch[x][f]]=y;
- pre[x]=pre[y];
- if(pre[x])
- ch[pre[y]][ch[pre[y]][]==y]=x;
- ch[x][f]=y;
- pre[y]=x;
- up(y);
- }
- void Splay(int x,int goal)
- {
- down(x);
- while(pre[x]!=goal)
- {
- down(pre[pre[x]]);
- down(pre[x]);
- down(x);
- if(pre[pre[x]]==goal)
- Rotate(x,ch[pre[x]][]==x);
- else
- {
- int y=pre[x],z=pre[y];
- int f=(ch[z][]==y);
- if(ch[y][f]==x)
- Rotate(x,!f),Rotate(x,f);
- else Rotate(y,f),Rotate(x,f);
- }
- }
- up(x);
- if(goal==)rt=x;
- }
- void RTO(int k,int goal)
- {
- int x=rt;
- down(x);
- while(sz[L]+!=k)
- {
- if(k<sz[L]+)x=L;
- else
- {
- k-=(sz[L]+);
- x=R;
- }
- down(x);
- }
- Splay(x,goal);
- }
- void vist(int x)
- {
- if(x)
- {
- printf("结点%2d : 左儿子 %2d 右儿子 %2d val: %2d sum=%lld\n",x,ch[x][],ch[x][],val[x],sum[x]);
- vist(L);
- vist(R);
- }
- }
- void debug()
- {
- puts(""); vist(rt); puts("");
- }
- void up(int x)
- {
- sz[x]=+sz[L]+sz[R];
- sum[x]=val[x]+sum[L]+sum[R];
- }
- void down(int x)
- {
- if(add[x])
- {
- val[L]+=add[x];
- val[R]+=add[x];
- add[L]+=add[x];
- add[R]+=add[x];
- sum[L]+=(LL)add[x]*sz[L];
- sum[R]+=(LL)add[x]*sz[R];
- add[x]=;
- }
- }
- void Newnode(int &x,int c,int f)
- {
- x=++top;
- L=R=; sz[x]=; pre[x]=f;
- val[x]=sum[x]=c;
- add[x]=;
- }
- void build(int &x,int l,int r,int f)
- {
- if(l>r)return;
- int m=(l+r)>>;
- Newnode(x,num[m],f);
- build(L,l,m-,x);
- build(R,m+,r,x);
- up(x);
- }
- void init(int n)
- {
- ch[][]=ch[][]=pre[]=;
- sz[]=rt=top=;
- add[]=sum[]=;
- Newnode(rt,-,);
- Newnode(ch[rt][],-,rt);
- sz[rt]=;
- for(int i=;i<=n;i++)
- scanf("%d",&num[i]);
- build(KT,,n,ch[rt][]);
- up(ch[rt][]);up(rt);
- }
- void update()
- {
- int l,r,c;
- scanf("%d%d%d",&l,&r,&c);
- RTO(l,);
- RTO(r+,rt);
- add[KT]+=c;
- val[KT]+=c;
- sum[KT]+=(LL)c*sz[KT];
- }
- void query()
- {
- int l,r;
- scanf("%d%d",&l,&r);
- RTO(l,);
- RTO(r+,rt);
- printf("%lld\n",sum[KT]);
- }
- LL sum[MAXN];
- int add[MAXN];
- int num[MAXN];
- }spt;
- int main()
- {
- int m,n;
- char op[];
- while(~scanf("%d%d",&n,&m))
- {
- spt.init(n);
- while(m--)
- {
- scanf("%s",op);
- if(op[]=='Q')spt.query();
- else spt.update();
- }
- }
- return ;
- }
线段树的题解
- // File Name: /home/neuacm/ACM/POJ/3468.cpp
- // Author: Zlbing
- // Created Time: 2013年08月09日 星期五 14时35分11秒
- #include<iostream>
- #include<string>
- #include<algorithm>
- #include<cstdlib>
- #include<cstdio>
- #include<set>
- #include<map>
- #include<vector>
- #include<cstring>
- #include<stack>
- #include<cmath>
- #include<queue>
- using namespace std;
- #define CL(x,v); memset(x,v,sizeof(x));
- #define INF 0x3f3f3f3f
- #define LL long long
- #define REP(i,r,n) for(int i=r;i<=n;i++)
- #define RREP(i,n,r) for(int i=n;i>=r;i--)
- #define lson l,m,rt<<1
- #define rson m+1,r,rt<<1|1
- const int MAXN=1e5+;
- LL col[MAXN<<];
- LL sum[MAXN<<];
- void pushup(int rt)
- {
- sum[rt]=sum[rt<<]+sum[rt<<|];
- }
- void pushdown(int rt,int l,int r)
- {
- if(col[rt])
- {
- col[rt<<]+=col[rt];
- col[rt<<|]+=col[rt];
- int m=(l+r)>>;
- sum[rt<<]+=(m-l+)*col[rt];
- sum[rt<<|]+=(r-m)*col[rt];
- col[rt]=;
- }
- }
- void build(int l,int r,int rt)
- {
- col[rt]=;
- if(l==r)
- {
- //scanf("%I64d",&sum[rt]);
- cin>>sum[rt];
- return ;
- }
- int m=(l+r)>>;
- build(lson);
- build(rson);
- pushup(rt);
- }
- LL query(int L,int R,int l,int r,int rt)
- {
- if(L<=l&&R>=r)
- {
- return sum[rt];
- }
- pushdown(rt,l,r);
- int m=(l+r)>>;
- LL ret=;
- if(L<=m)ret+=query(L,R,lson);
- if(R>m)ret+=query(L,R,rson);
- return ret;
- }
- void update(int L,int R,int p,int l,int r,int rt)
- {
- if(L<=l&&R>=r)
- {
- col[rt]+=p;
- sum[rt]+=(r-l+)*p;
- return;
- }
- pushdown(rt,l,r);
- int m=(l+r)>>;
- if(L<=m)update(L,R,p,lson);
- if(R>m)update(L,R,p,rson);
- pushup(rt);
- }
- void debug(int l,int r,int rt)
- {
- if(l==r)
- {
- printf("l==%d r==%d rt=%d sum[rt]=%lld col[rt]=%lld\n",l,r,rt,sum[rt],col[rt]);
- return ;
- }
- printf("l==%d r==%d rt=%d sum[rt]=%lld col[rt]=%lld\n",l,r,rt,sum[rt],col[rt]);
- int m=(l+r)>>;
- debug(lson);
- debug(rson);
- }
- int main()
- {
- int n,m;
- //std::ios::sync_with_stdio(false);
- while(~scanf("%d%d",&n,&m))
- {
- build(,n,);
- char ch[];
- int a,b,c;
- REP(i,,m)
- {
- scanf("%s",ch);
- if(ch[]=='Q')
- {
- scanf("%d%d",&a,&b);
- LL ans=query(a,b,,n,);
- //debug(1,n,1);
- cout<<ans<<endl;
- }
- else if(ch[]=='C')
- {
- scanf("%d%d%d",&a,&b,&c);
- update(a,b,c,,n,);
- //debug(1,n,1);
- }
- }
- }
- return ;
- }
POJ-3468-A Simple Problem with Integers(区间更新,求和)-splay或线段树的更多相关文章
- POJ.3468 A Simple Problem with Integers(线段树 区间更新 区间查询)
POJ.3468 A Simple Problem with Integers(线段树 区间更新 区间查询) 题意分析 注意一下懒惰标记,数据部分和更新时的数字都要是long long ,别的没什么大 ...
- poj 3468 A Simple Problem with Integers 【线段树-成段更新】
题目:id=3468" target="_blank">poj 3468 A Simple Problem with Integers 题意:给出n个数.两种操作 ...
- 线段树(成段更新) POJ 3468 A Simple Problem with Integers
题目传送门 /* 线段树-成段更新:裸题,成段增减,区间求和 注意:开long long:) */ #include <cstdio> #include <iostream> ...
- POJ 3468 A Simple Problem with Integers(线段树功能:区间加减区间求和)
题目链接:http://poj.org/problem?id=3468 A Simple Problem with Integers Time Limit: 5000MS Memory Limit ...
- poj 3468 A Simple Problem with Integers(线段树+区间更新+区间求和)
题目链接:id=3468http://">http://poj.org/problem? id=3468 A Simple Problem with Integers Time Lim ...
- POJ 3468 A Simple Problem with Integers(线段树&区间更新)题解
Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. On ...
- POJ 3468 A Simple Problem with Integers(分块入门)
题目链接:http://poj.org/problem?id=3468 A Simple Problem with Integers Time Limit: 5000MS Memory Limit ...
- poj 3468 A Simple Problem with Integers 线段树区间加,区间查询和
A Simple Problem with Integers Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?i ...
- poj 3468 A Simple Problem with Integers 线段树区间加,区间查询和(模板)
A Simple Problem with Integers Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?i ...
- poj 3468:A Simple Problem with Integers(线段树,区间修改求和)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 58269 ...
随机推荐
- 【Android】android镜像翻转
Android镜像翻转指的是将屏幕进行水平的翻转,达到所有内容显示都会反向的效果,就像是在镜子中看到的界面一样.这种应用的使用场景相对比较受限,主要用在一些需要使用Android手机界面进行镜面投影的 ...
- install erlang environment on centos
#(erlide in linux can't detect the runtime if build from source, but erlang shell works correctly)su ...
- &与&
- java中怎么进行字符串替换?
String str = "test.doc"; String newStr = str.replaceAll("doc","html");
- 常用的dos命令之简略总结
Dos常用命令 一.基础命令 1 dir 无参数:查看当前所在目录的文件和文件夹. /s:查看当前目录已经其所有子目录的文件和文件夹. /a:查看包括隐含文件的所有文件. /ah:只显示出 ...
- 关于 ASP.NET 验证码
Session["CheckCode"] 这个..不懂神马意思.. .创建一个用户控件 用户名:TextBox 密码: TextBox 验证码:TextBox 验证码图片 < ...
- hdoj 2602(背包)
Problem D Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Total Sub ...
- Qt Creator编译问题
有时候需要自己编译Qt Creator,需要注意的就是qmake版本的问题,比如我用4.8.1和4.8.6同样编译出来的Qt Creator在同样的qtconfig-qt4下所呈现的效果是不一样的. ...
- WARN [main] conf.HiveConf (HiveConf.java:initialize(1488)) - DEPRECATED
问题描述:hive 关于告警问题的解决:WARN [main] conf.HiveConf (HiveConf.java:initialize(1488)) - DEPRECATED: Config ...
- chrome调试状态下动态加载的js
在js文件中加入 //@ sourceURL=文件名.js