POJ 3468-线段数区间更新
2017-11-10 02:25
197 查看
POJ 3468
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 51 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
455
9
15
Hint
The sums may exceed the range of 32-bit integers.题目大意:给你一堆数,在区间里进行各种操作,询问区间的和、注意sum、和seg的数据类型是long long
真的是艰难,经历了3个小时终于A掉了,不过还是值得的。这样一来对线段树的区间更新认识更加深刻了,回来再把区间更新的原理写出来吧,虽然不是很困,但是时间真的有点晚了,我还有点饿
区间更新、区间求和更新延迟标记时注意
标记的叠加、叠加、叠加…省略无数次叠加
Pushdown
void Pushdown(int l,int r,int i) {//操作结果延迟标记下压子区间 //同时更新子区间区间的sum if(tree[i].seg==0) return ; int m=(l+r)>>1; tree[i<<1].seg+=tree[i].seg;//注意这里是叠加 tree[i<<1].sum+=tree[i].seg*(m-l+1); tree[i<<1|1].seg+=tree[i].seg; tree[i<<1|1].sum+=tree[i].seg*(r-m); tree[i].seg=0;//清楚延迟标记 }
Update
void Update(int L,int R,int l,int r,int i,long long e) { //操作结果将目标区间打上延迟标记,更新路径上的sum if(L<=l&&R>=r) { tree[i].seg+=e;//这里是细节 tree[i].sum+=(long long)(e*(r-l+1)); return; } Pushdown(l,r,i); int m=(l+r)>>1; if(L<=m) Update(L,R,lson,e); if(R>m) Update(L,R,rson,e); Pushup(i); }
#include<iostream>
#include<cstdio>
#include<cstring>
#define lson l,m,i<<1
#define rson m+1,r,i<<1|1
using namespace std;
const int maxn=100005;
struct node
{
int left,right;
long long sum;
long long seg;
}tree[maxn<<2];
void Pushup(int i)
{
tree[i].sum=tree[i<<1].sum+tree[i<<1|1].sum;
}
void Pushdown(int l,int r,int i) {//操作结果延迟标记下压子区间 //同时更新子区间区间的sum if(tree[i].seg==0) return ; int m=(l+r)>>1; tree[i<<1].seg+=tree[i].seg;//注意这里是叠加 tree[i<<1].sum+=tree[i].seg*(m-l+1); tree[i<<1|1].seg+=tree[i].seg; tree[i<<1|1].sum+=tree[i].seg*(r-m); tree[i].seg=0;//清楚延迟标记 }
void Build(int l,int r,int i)
{
tree[i].left=l;
tree[i].right=r;
if(l==r)
{
scanf("%lld",&tree[i].sum);
return ;
}
int m=(l+r)>>1;
Build(lson);
Build(rson);
Pushup(i);
}
void Update(int L,int R,int l,int r,int i,long long e) { //操作结果将目标区间打上延迟标记,更新路径上的sum if(L<=l&&R>=r) { tree[i].seg+=e;//这里是细节 tree[i].sum+=(long long)(e*(r-l+1)); return; } Pushdown(l,r,i); int m=(l+r)>>1; if(L<=m) Update(L,R,lson,e); if(R>m) Update(L,R,rson,e); Pushup(i); }
long long Query(int L,int R,int l,int r,int i)
{//操作结果 求区间和、跟新途中延迟标记
if(L<=l&&R>=r)
{
return tree[i].sum;
}
long long ans=0;
Pushdown(l,r,i);
int m=(l+r)>>1;
if(L<=m)
ans+=Query(L,R,lson);
if(R>m)
ans+=Query(L,R,rson);
return ans;
}
int main()
{
memset(tree,0,sizeof(tree));
int N,Q;
cin>>N>>Q;
Build(1,N,1);
for(int j=1;j<=Q;j++)
{
int a,b,c;
char str;
cin>>str;
if(str=='Q')
{
cin>>a>>b;
cout<<Query(a,b,1,N,1)<<endl;
}
if(str=='C')
{
cin>>a>>b>>c;
Update(a,b,1,N,1,c);
}
}
return 0;
}
相关文章推荐
- POJ 3468 A Simple Problem with Integers // 线段树 区间更新
- POJ-3468(线段树_区间更新)
- poj 3468 A Simple Problem with Integers(线段树——区间更新)
- 线段树 + 区间更新 + 模板 ---- poj 3468
- POJ 3468 - A Simple Problem with Integers(线段树,区间更新)
- poj 3468 线段树区间更新 lazy思想
- POJ_3468_Interval Tree 更新区间经典
- 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 线段树(区间更新)
- poj 3468 A Simple Problem with Integers 线段树 区间更新求和
- POJ 3468 【线段树区间更新-成段更新】
- POJ 3468 A Simple Problem with Integers 【线段树,区间更新】
- poj3468线段树区间更新
- poj 3468 A Simple Problem with Integers(线段树——区间更新)
- POJ 3468 - A Simple Problem with Integers(线段树区间更新+模板)
- POJ 3468 线段树区间更新
- POJ 3468 A Simple Problem with Integers 【线段树,区间更新】