[POJ3468]A Simple Problem with Integers

本文介绍了一道关于线段树区间更新与查询的经典题目,并提供了完整的C++代码实现。文章详细展示了如何通过线段树解决区间加法更新及求区间和的问题。

题目链接:http://poj.org/problem?id=3468

线段树区间更新查询的样题,注意数据范围。连要更新的数据也必须是long long。

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <iomanip>
 4 #include <cstring>
 5 #include <climits>
 6 #include <complex>
 7 #include <cassert>
 8 #include <cstdio>
 9 #include <bitset>
10 #include <vector>
11 #include <deque>
12 #include <queue>
13 #include <stack>
14 #include <ctime>
15 #include <set>
16 #include <map>
17 #include <cmath>
18 using namespace std;
19 
20 typedef long long LL;
21 #define lrt rt << 1
22 #define rrt rt << 1 | 1
23 const int maxn = 100100;
24 LL sum[maxn<<2], add[maxn<<2];
25 int n, q;
26 char cmd[2];
27 
28 void pushUP(int rt) {
29     sum[rt] = sum[lrt] + sum[rrt];
30 }
31 
32 void pushDOWN(int rt, int len) {
33     if(add[rt]) {
34         sum[lrt] += (len - len / 2) * add[rt];
35         sum[rrt] += len / 2 * add[rt];
36         add[lrt] += add[rt];
37         add[rrt] += add[rt];
38         add[rt] = 0;
39     }
40 }
41 
42 void build(int l, int r, int rt) {
43     add[rt] = 0;
44     if(l == r) {
45         scanf("%I64d", &sum[rt]);
46         return;
47     }
48     int mid = (l + r) >> 1;
49     build(l, mid, lrt);
50     build(mid+1, r, rrt);
51     pushUP(rt);
52 }
53 
54 void update(int L, int R, LL c, int l, int r, int rt) {
55     if(L <= l && r <= R) {
56         add[rt] += c;
57         sum[rt] += (LL)c * (r - l + 1);
58         return;
59     }
60     pushDOWN(rt, r-l+1);
61     int mid = (l + r) >> 1;
62     if(L <= mid) update(L, R, c, l, mid, lrt);
63     if(mid < R) update(L, R, c, mid+1, r, rrt);
64     pushUP(rt);
65 }
66 
67 LL query(int L, int R, int l, int r, int rt) {
68     if(L <= l && r <= R) return sum[rt];
69     pushDOWN(rt, r-l+1);
70     int mid = (l + r) >> 1;
71     LL ret = 0;
72     if(L <= mid) ret += query(L, R, l, mid, lrt);
73     if(mid < R) ret += query(L, R, mid+1, r, rrt);
74     return ret;
75 }
76 
77 int main() {
78     // freopen("in", "r", stdin);
79     int l, r, c;
80     while(~scanf("%d%d",&n,&q)) {
81         build(1, n, 1);
82         while(q--) {
83             scanf("%s", cmd);
84             if(cmd[0] == 'Q') {
85                 scanf("%d%d",&l,&r);
86                 printf("%I64d\n", query(l,r,1,n,1));
87             }
88             else {
89                 scanf("%d%d%d",&l,&r,&c);
90                 update(l,r,LL(c),1,n,1);
91             }
92         }
93     }
94     return 0;
95 }

 

转载于:https://www.cnblogs.com/kirai/p/4771834.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值