A Simple Problem with Integers_poj3468_线段树
2016-11-23 20:37
483 查看
Description
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.Analysis
一直只知道线段树如何单点操作,后来才发现有区间操作的精髓被我遗弃了。今天补上关于lazyTag
延迟标记,当我们需要对某一区间连续修改时,我们可以先不管他,用一个下标lazy记录对应区间修改,遇到查询问题的时候往下传递lazy,这样就能保证修改和查询的复杂度是logn的这题是很裸的区间修改查询,树状数组也能做,就当练手吧
Code
#include <stdio.h> #define N 100001 #define ll __int64 using namespace std; struct tree{int l,r;ll lazy,sum;}t[N<<2+1]; void build(int f,int x,int y) { t[f].l=x;t[f].r=y; if (x==y) { scanf("%I64d",&t[f].sum); return; } int mid=(x+y)>>1; build(f*2,x,mid); build(f*2+1,mid+1,y); t[f].sum=t[f*2].sum+t[f*2+1].sum; } void pushDown(int f,int len) { t[f*2].lazy+=t[f].lazy; t[f*2+1].lazy+=t[f].lazy; t[f*2].sum+=t[f].lazy*(len-len/2); t[f*2+1].sum+=t[f].lazy*(len/2); t[f].lazy=0; } void modify(int f,int x,int y,ll v) { if (x<=t[f].l&&y>=t[f].r) { t[f].lazy+=v; t[f].sum+=(t[f].r-t[f].l+1)*v; return; } if (t[f].lazy) pushDown(f,t[f].r-t[f].l+1); int mid=(t[f].l+t[f].r)>>1; if (y<=mid) modify(f*2,x,y,v); else if (x>mid) modify(f*2+1,x,y,v); else modify(f*2,x,mid,v),modify(f*2+1,mid+1,y,v); t[f].sum=t[f*2].sum+t[f*2+1].sum; } ll query(int f,int x,int y) { if (x<=t[f].l&&y>=t[f].r) return t[f].sum; if (t[f].lazy) pushDown(f,t[f].r-t[f].l+1); int mid=(t[f].l+t[f].r)>>1; if (y<=mid) return query(f*2,x,y); else if (x>mid) return query(f+f+1,x,y); else return query(f+f,x,mid)+query(f+f+1,mid+1,y); } int main() { int n,m; scanf("%d%d",&n,&m); build(1,1,n); for (int i=1;i<=m;i++) { int x,y; char opt; ll v; getchar(); scanf("%c%d%d",&opt,&x,&y); if (opt=='C') { scanf("%I64d",&v); modify(1,x,y,v); } else printf("%I64d\n",query(1,x,y)); } return 0; }
相关文章推荐
- (线段树、树状数组)poj3468-A Simple Problem with Integers
- poj3468 A Simple Problem with Integers 线段树,成段更新
- poj3468 A Simple Problem with Integers 线段树lazy标签
- POJ3468 A Simple Problem with Integers 线段树|树状数组BIT(区间增减,求和)
- poj3468-A Simple Problem with Integers 线段树成段增减,区域求和(延迟标记)
- POJ3468 A Simple Problem with Integers 线段树成段更新
- 【POJ3468】【zkw线段树】A Simple Problem with Integers
- poj3468 A Simple Problem with Integers 线段树懒惰树
- POJ3468 A Simple Problem with Integers(线段树延时标记)
- poj3468 A Simple Problem with Integers(线段树区间修改)
- POJ3468 A Simple Problem with Integers(线段树成段更新,区间查询)
- POJ3468 A Simple Problem with Integers 线段树 区间成段更新+区间求和
- poj3468 A Simple Problem with Integers (线段树的懒惰标记)
- poj3468 A Simple Problem with Integers(线段树模板 功能:区间增减,区间求和)
- poj3468 A Simple Problem with Integers(线段树成段更新)
- poj3468 A Simple Problem with Integers(线段树,区间更新,区间和查询)
- POJ3468 A Simple Problem with Integers(线段树)
- POJ3468 A Simple Problem with Integers(线段树)
- poj3468 A Simple Problem with Integers 线段树入门题复习
- poj3468 A Simple Problem with Integers(spaly&&线段树)