文章标题 POJ 3468 : A Simple Problem with Integers (线段树)
来源:互联网 发布:c语言成绩查询系统湖北 编辑:程序博客网 时间:2024/06/06 19:13
A Simple Problem with Integers
You have N integers, A1, A2, … , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.
Input
The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1, A2, … , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
“C a b c” means adding c to each of Aa, Aa+1, … , Ab. -10000 ≤ c ≤ 10000.
“Q a b” means querying the sum of Aa, Aa+1, … , Ab.
Output
You need to answer all Q commands in order. One answer in a line.
Sample Input
10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4
Sample Output
4
55
9
15
Hint
The sums may exceed the range of 32-bit integers.
题意:有一个n个数的序列,然后有q个查询,每次查询有两种可能,第一中就是将区间【l,r】全部加上val,第二种就是将区间【l,r】所有的和sum。
分析:线段树区间求和,用sum来保存节点做在区间的和,然后用一个lazy标记setv数组,当需要向下更新再想下更新,不然lazy标记就是保存最新的值。
代码:
#include<iostream>#include<string>#include<cstdio>#include<cstring>#include<vector>#include<math.h>#include<map>#include<queue> #include<algorithm>using namespace std;const int inf = 0x3f3f3f3f;typedef pair<int,int> pii;const int maxn=100005<<2;int n,q;long long sum[maxn];//节点的sum值 long long val[maxn]; long long setv[maxn];//lazy标记 void push_up(int rt){//向上更新 sum[rt]=sum[rt*2]+sum[rt*2+1];}void push_down(int rt,int len){ if (setv[rt]){//有lazy标记就向左右孩子传递,自己改为0 setv[rt*2]+=setv[rt]; setv[rt*2+1]+=setv[rt]; sum[rt*2]+=(len-len/2)*setv[rt]; sum[rt*2+1]+=(len/2)*setv[rt]; setv[rt]=0; }} void build(int rt,int l,int r){//建树 setv[rt]=0; if (l==r){ scanf ("%lld",&sum[rt]); return ; } int m=(l+r)>>1; build(rt*2,l,m); build(rt*2+1,m+1,r); push_up(rt);}long long query(int rt,int l,int r,int ql,int qr){ if (ql<=l&&r<=qr){//如果当前的区间在需要的查询的区间内直接返回 return sum[rt]; } int mid=(l+r)>>1; push_down(rt,(r-l+1));//向下传递 long long ans=0; if (ql<=mid){//如果有查询的区间有一部分在当前节点的左孩子 ans+=query(rt*2,l,mid,ql,qr); } if (qr>mid){//有部分查询的区间在当前节点的右孩子 ans+=query(rt*2+1,mid+1,r,ql,qr); } push_up(rt);//向上更新 return ans;}//在区间[ul,ur]加上val void update(int rt,int l,int r,int ul,int ur,int val){ if (ul<=l&&r<=ur){//当前的区间包括在查询的区间之内 setv[rt]+=val; sum[rt]+=(long long)(r-l+1)*val; }else{ push_down(rt,r-l+1);//如果没有全部包括则向下更新 int mid=(l+r)>>1; if (ul<=mid){ update(rt*2,l,mid,ul,ur,val); } if (mid<ur) { update(rt*2+1,mid+1,r,ul,ur,val); } push_up(rt); }}int main (){ while (scanf ("%d%d",&n,&q)!=EOF){ build(1,1,n);//建树 char ch[10]; long long a,b,val; while (q--){ scanf ("%s",ch); if (ch[0]=='C'){ scanf ("%lld%lld%lld",&a,&b,&val); update(1,1,n,a,b,val);//更新 }else { scanf ("%d%d",&a,&b); long long ans=query(1,1,n,a,b);//查询 printf ("%lld\n",ans); } } } return 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 main函数的命令行参数
- JVM内存管理机制
- 重载运算符时的参数和返回类型要用引用的说明
- java.io.IOException: Connection reset by peer
- 设计模式-策略模式
- 文章标题 POJ 3468 : A Simple Problem with Integers (线段树)
- SQLiteOpenHelper 用单例模式实现后 onCreate 方法不执行的解决过程
- 《数据结构(C语言版)》- 绪论
- jqGrid学习
- 北京科技大学-银行系统设计基础知识分享
- 第12篇:ng-class的用法
- Ajax
- 【二叉树】二分查找树,节点删除【Add to List 450. Delete Node in a BST】
- 查看Linux下端口占用情况的命令