【POJ - 3468 】 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 4Sample Output
4 55 9 15Hint
The sums may exceed the range of 32-bit integers.
解題報告:
? ? ? ?有的同學會說,這不是動態(tài)差分數(shù)組嗎?所以可以樹狀數(shù)組啊,樹狀數(shù)組的單點查詢區(qū)間更新就是進化版的差分數(shù)組啊,是這樣說沒錯,但是你要知道,單點查詢是動態(tài)的,但是這里是區(qū)間查詢,所以你需要算前綴和,而前綴和是離線查詢的!不能動態(tài)
AC代碼:
#include<bits/stdc++.h> #define ll long long using namespace std; const int MAX = 100000 + 5; int n,m; struct TREE {int l,r;ll val;ll laz; } tree[4*MAX]; int a[MAX]; void pushup(int cur) {tree[cur].val = tree[2*cur].val + tree[2*cur + 1].val; } void pushdown(int l,int r,int cur) {if(tree[cur].laz == 0) return ;int m = (l + r)/2;tree[2*cur].val += (m-l+1) * tree[cur].laz;tree[2*cur].laz += tree[cur].laz;tree[2*cur+1].val += (r-m) * tree[cur].laz;tree[2*cur+1].laz += tree[cur].laz;tree[cur].laz = 0; } void build(int l,int r,int cur) {if(l == r) {tree[cur].l = tree[cur].r = l;tree[cur].val = a[r];tree[cur].laz = 0;return ;}int m = (l+r)/2;tree[cur].l = l; tree[cur].r = r;build(l,m,2*cur);build(m+1,r,2*cur+1);pushup(cur); } void update(int pl,int pr,ll val,int l,int r,int cur) {if(pl <= l && pr >= r) {tree[cur].val += (r-l+1)*val;tree[cur].laz += val;return ;}pushdown(l,r,cur);int m = (l + r)/2;if(pl <= m) update(pl,pr,val,l,m,2*cur);if(pr >= m+1) update(pl,pr,val,m+1,r,2*cur+1);pushup(cur); } ll query(int pl,int pr,int l,int r,int cur) {if(pl <= l && pr >= r) return tree[cur].val;pushdown(l,r,cur);int m = (l+r)/2;ll ans = 0 ;if(pl <= m ) ans += query(pl,pr,l,m,2*cur);if(pr >= m+1) ans += query(pl,pr,m+1,r,2*cur+1);//別寫成cur了 return ans; } int main() {cin>>n>>m;int tmp1,tmp2;ll tmp3;char op[10];for(int i = 1; i<=n; i++) {scanf("%lld",&a[i]);}build(1,n,1);while(m--) {scanf("%s",op);if(op[0] == 'C') {scanf("%d%d%lld",&tmp1,&tmp2,&tmp3); update(tmp1,tmp2,tmp3,1,n,1);}else {scanf("%d%d",&tmp1,&tmp2);printf("%lld\n",query(tmp1,tmp2,1,n,1));}}return 0 ;}總結:
? ? 1WA了,因為pushdown的laz修改的時候有個地方寫成了= ?應該是+=?
總結
以上是生活随笔為你收集整理的【POJ - 3468 】 A Simple Problem with Integers (线段树模板 区间更新 + 区间和查询)(不能树状数组或差分数组)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【HDU - 1257】最少拦截系统 (
- 下一篇: 2017平安银行信用卡有效期:延长至8年