POJ 3468A Simple Problem with Integers(线段树)
来源:互联网 发布:成都网络棋牌公司 编辑:程序博客网 时间:2024/05/29 02:09
给出了一个序列,你需要处理如下两种询问。
"C a b c"表示给[a, b]区间中的值全部增加c (-10000 ≤ c ≤ 10000)。
"Q a b" 询问[a, b]区间中所有值的和。
第一行包含两个整数N, Q。1 ≤ N,Q ≤ 100000.
第二行包含n个整数,表示初始的序列A (-1000000000 ≤ Ai ≤ 1000000000)。
接下来Q行询问,格式如题目描述。
Sample Input
10 51 2 3 4 5 6 7 8 9 10Q 4 4Q 1 10Q 2 4C 3 6 3Q 2 4
Sample Output
455915
这道题也比较简单,成段更新
体现了线段树的好处
不过要注意这里增加了两个方法 pushdown和pushup
pushup就是向上更新,也就是说父节点的和是两个子节点的和相加 从叶子节点累加上去到了根节点的话,最终根节点的和就是所有叶子节点的值加起来
有点像BOSS拿的钱就是各个小弟拿的钱加起来 就那么个意思~
pushdown就是向下更新,也就是说 比如你输入了 C 1 4 1也就是在第1个数到第4个数全部加1
首先你就要找到1 到4 然后在1到4 下面的1 到 2 和 3 到 4 把要加的数也就是1 加上去 依次类推在 1 到 2 下面的1 和 2 加上1
那么结果就是你在 1 2 3 4这四个叶子节点中的值都加了1,在这里有两个要维护的域 一个是“加多少” tree[i].add ,另外一个是“加了之后是多少” tree[i].sum
在update中的
if(A<=l&&B>=r) { tree[i].add+=C; tree[i].sum+=C*(r-l+1); return ; }r-l+1是这段区间的长度也就是线段长度,比如上面所说的例子如果恰好是1 到 4 的话直接可以在 1 到4线段中加上 1*4=4 此次update就完成了
说到这里已经很清楚了,下面上代码:
#include<cstdio>#define N 100005int n,m;long long num[N];struct node{ int l,r; long long sum; long long add;} tree[N<<2];void pushup(int i){ tree[i].sum=tree[i<<1].sum+tree[i<<1|1].sum;}void build(int l,int r,int i){ tree[i].l=l; tree[i].r=r; if(l==r) { tree[i].sum=num[l]; return ; } int mid=(l+r)>>1; build(l,mid,i<<1); build(mid+1,r,i<<1|1); pushup(i);}void pushdown(int rt,int dis){ if(tree[rt].add) { tree[rt<<1].add+=tree[rt].add; tree[rt<<1|1].add+=tree[rt].add; tree[rt<<1].sum+=tree[rt].add*(dis-(dis>>1)); tree[rt<<1|1].sum+=tree[rt].add*(dis>>1); tree[rt].add=0; }}void update(int A,int B,int C ,int l,int r,int i){ if(A<=l&&B>=r) { tree[i].add+=C; tree[i].sum+=C*(r-l+1); return ; } pushdown(i,r-l+1); int mid=(l+r)>>1; if(A<=mid)update(A,B,C,l,mid,i<<1); if(B>mid)update(A,B,C,mid+1,r,i<<1|1); pushup(i);}long long query(int A,int B,int l,int r,int i){ if(A<=l&&B>=r) { return tree[i].sum; } pushdown(i,r-l+1); long long ans=0; int mid=(l+r)>>1; if(A<=mid) ans+=query(A,B,l,mid,i<<1); if(B>mid) ans+=query(A,B,mid+1,r,i<<1|1); return ans;}int main(){ scanf("%d%d",&n,&m); for(int i=1; i<=n; i++) scanf("%I64d",&num[i]); build(1,n,1); while(m--) { char s[6]; int a,b,c; scanf("%s",&s); if(s[0]=='C') { scanf("%d%d%d",&a,&b,&c); update(a,b,c,1,n,1); } else { scanf("%d%d",&a,&b); printf("%I64d\n",query(a,b,1,n,1)); } } 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(线段树)
- 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----线段树
- POJ 3468 A Simple Problem with Integers(线段树)
- poj-3468-A Simple Problem with Integers(线段树)
- java获取各种格式的时间,获取昨天明天日期,获取一天的开始结束时间
- Maven 那点事儿
- matlab 判断两个矩阵是否相等
- 内部类的概述和讲解
- Mycat连续分片(自定义数字范围分片)学习
- POJ 3468A Simple Problem with Integers(线段树)
- goke开发杂记
- -Dmaven.multiModuleProjectDirectory system property is not set. Check $M2_HOME environment variable
- 哈希冲突的概率
- Hduojo1059【01背包】
- jni入门
- 【CSS3】background-origin
- 获得除任务栏外桌面可用区域
- android之TheadLocal,还有Handler