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群英传》读书笔记 (3) 第六章 Android绘图机制与处理技巧 + 第七章 Android动画机制与使用技巧
第六章 Android绘图机制与处理技巧 1.屏幕尺寸信息屏幕大小:屏幕对角线长度,单位“寸”:分辨率:手机屏幕像素点个数,例如720x1280分辨率:PPI(Pixels Per Inch):即DP ...
- Java基础知识强化之集合框架笔记45:Set集合之TreeSet存储自定义对象并遍历练习1(自然排序:Comparable)
1. 自然排序: TreeSet会调用集合元素的compareTo(Object obj)方法来比较元素之间的大小关系,然后将集合元素按照升序排列,这种方式就是自然排序. Java中提供了一个Comp ...
- Linux 目录与文件的基本操作
1 目录与文件 1.1 文件 硬盘中的数据在操作系统中的体现为文件. 1.2 目录 目录的概念不是文件集合.目录和文件一样,目录也是文件.目录是找到文件的“踏板”.目录的本质是路径映射. 1.3 Li ...
- ES6数组去重
今天五一,在出去玩之前赶紧写篇博客,时刻不要忘记学习^_^!! 提到数组去重,想必大家都不陌生,会的同学可能噼里啪啦写出好几个,下面来看看之前常见的去重代码: 'use strict'; var ar ...
- IntelliJ IDEA 14
新接触IntelliJ IDEA 14,使用起来还不是很称手,每天在使用中学习吧. 每学到一个新技能就来更新一下. (2015.11.17) " Ctrl + / " 代码批量注释 ...
- 硬编码写RadioGroup的时候要注意设置RadioButton的Id
硬编码写RadioGroup的时候要注意RadioButton的id重复问题,导致选择的时候出现能够多选的情况发生,如下代码,注意Id的设置,这样避免Radiobutton的id重复. /** * 生 ...
- 关于Android4.x系统默认显示方向各种修改
1.设置属性值 在device.mk文件中加入PRODUCT_PROPERTY_OVERRIDES += \ ro.sf.hwrotation=180 2.设置屏幕默认显示方向 在frameworks ...
- Html5 部分特性
HTML5 是 W3C 与 WHATWG 合作的结果. 编者注:W3C 指 World Wide Web Consortium,万维网联盟. 编者注:WHATWG 指 Web Hypertext Ap ...
- TreeView checkbox
C# TreeView checkbox 联动打勾 #region 将树的checkbox选中 private void setNodeTrue(Node selNode) { Node node = ...
- Windows7添加SSD硬盘后重启卡住正在启动
楼主办公电脑,原来只配置了一块机械硬盘,用着总很不顺心,于是说服领导给加了块SSD固态硬盘. 操作如下: 1.在PE下分区格式化新固态硬盘,将原来机械硬盘的C盘GHOST备份后还原到新固态硬盘: 2. ...