POJ 3468 A Simple Problem with Integers(线状树经典模型之lazy操作)
2016-04-21 19:48
519 查看
A Simple Problem with Integers
Crawling in process...Crawling failed
Time Limit:5000MS Memory Limit:131072KB 64bit IO Format:%I64d & %I64u
POJ
3468
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 numbersN 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 abc" means adding c to each of Aa, Aa+1, ... ,Ab. -10000 ≤
c ≤ 10000.
"Q ab" means querying the sum of Aa, Aa+1, ... ,Ab.
Output
You need to answer allQ commands in order. One answer in a line.
Sample Input
Sample Output
Hint
The sums may exceed the range of 32-bit integers.
区间更新区间求和。
这里就要涉及到懒操作。注意的是lazy被更新的区间一定是当前的区间和已经更新完
>>AC代码:
Crawling in process...Crawling failed
Time Limit:5000MS Memory Limit:131072KB 64bit IO Format:%I64d & %I64u
POJ
3468
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 numbersN 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 abc" means adding c to each of Aa, Aa+1, ... ,Ab. -10000 ≤
c ≤ 10000.
"Q ab" means querying the sum of Aa, Aa+1, ... ,Ab.
Output
You need to answer allQ 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.
区间更新区间求和。
这里就要涉及到懒操作。注意的是lazy被更新的区间一定是当前的区间和已经更新完
>>AC代码:
#include<cstdio> #include<cstring> #include<queue> #include<iostream> #include<math.h> #include<algorithm> using namespace std; typedef long long ll; int N,M; ll b[101000]; struct zxs{ int l,r; ll sum,lazy; }tree[101000*4]; void build(int id,int l,int r){ tree[id].l=l; tree[id].r=r; tree[id].lazy=0; if(l==r){ tree[id].sum=b[l]; return;} int mid=(r+l)/2; build(id*2,l,mid); build(id*2+1,mid+1,r); tree[id].sum=tree[id*2].sum+tree[id*2+1].sum; } void push_down(int id ){ if(tree[id].lazy==0)return ;//这个预判注意...... tree[id*2].sum+=tree[id].lazy*(tree[id*2].r-tree[id*2].l+1); tree[id*2].lazy+=tree[id].lazy; tree[id*2+1].sum+=tree[id].lazy*(tree[id*2+1].r-tree[id*2+1].l+1); tree[id*2+1].lazy+=tree[id].lazy; tree[id].lazy=0; } void update(int id,int x,int y,ll n){ if(tree[id].l>=x&&tree[id].r<=y){ tree[id].lazy+=n; tree[id].sum+=n*(tree[id].r-tree[id].l+1);//这样才是对的 //也可以写成tree[id].sum+=n*(y-x+1);但这个从理解上来说是错的,改成这样也能AC,为什么? //经过一番思考,终于得到答案:如果一开始tree[id].l==x&&tree[id].r==y那么这样加是等效的,肯定没有错 //如果一开始x,y的区间不满足上述条件,那么可以看见在update末尾是有一个 tree[id].sum=tree[id*2].sum+tree[id*2+1].sum,也就是最终还有一次彻底的正确的更新, 因此也不会错,但是为了规范,一定得写成正确的tree[id].sum+=n*(tree[id].r-tree[id].l+1); return;} push_down(id); int l=tree[id].l; int r=tree[id].r; int mid=(r+l)/2; if(mid<x) update(id*2+1,x,y,n); else if(y<=mid) update(id*2,x,y,n); else {update(id*2,x,mid,n); update(id*2+1,mid+1,y,n); } tree[id].sum=tree[id*2].sum+tree[id*2+1].sum; } ll query(int id,int x,int y){ if(x<=tree[id].l&&tree[id].r<=y){return tree[id].sum;} //刚开始写成x>=tree[id].l.......吐血WA。 push_down(id); int l=tree[id].l; int r=tree[id].r; int mid=(l+r)/2; if(y<=mid){return query(id*2,x,y);} else if(x>mid){return query(id*2+1,x,y);} else{ return query(id*2,x,mid)+query(id*2+1,mid+1,y); } } int main(){ while(scanf("%d%d",&N,&M)!=EOF){ int x1,x2; long long x3; for(int i=1;i<=N;i++) scanf("%lld",b+i); //再次吐血,I写成l build(1,1,N); char s[10]; for(int i=0;i<M;i++){ scanf("%s",s); if(s[0]=='Q'){ scanf("%d%d",&x1,&x2); cout<<query(1,x1,x2)<<endl;} else{ scanf("%d%d%lld",&x1,&x2,&x3); //64位输出用%lld最方便了,不要写成%I64d不然等下I写成L又出bug了! //细节决定成败! update(1,x1,x2,x3); } } } return 0; }
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++高级程序员成长之路
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C与C++之间相互调用实例方法讲解
- 解析C++中派生的概念以及派生类成员的访问属性