线段树(成段更新) 之 poj 3468 A Simple Problem with Integers

来源:互联网 发布:淘宝买家秀合集 编辑:程序博客网 时间:2024/06/05 11:27
//  [7/29/2014 Sjm]/*线段树称断更新。。。关键lazy思想,保存增量,更新时只更新到某一段,不再向下更新,待再次更新或查询到此段时,对其子节点进行更新。。*/
#include <iostream>#include <cstdlib>#include <cstdio>#include <cstring>#include <string>using namespace std;typedef __int64 int64;#define lson l, m, rt<<1#define rson m+1, r, rt<<1 | 1#define GetMid(l, r) l+((r-l)>>1)const int MAX_N = 100005;int N, Q;int64 Sum[MAX_N << 2], Mark[MAX_N << 2];void PushUp(int rt) { Sum[rt] = Sum[rt << 1] + Sum[rt << 1 | 1]; }void PushDown(int rt, int len) {if (Mark[rt]) {Mark[rt << 1] += Mark[rt];Mark[rt << 1 | 1] += Mark[rt];Sum[rt << 1] += (len - (len >> 1))*Mark[rt];Sum[rt << 1 | 1] += (len >> 1)*Mark[rt];Mark[rt] = 0;}}void Build(int l, int r, int rt) {Mark[rt] = 0;if (l == r) { scanf("%I64d", &Sum[rt]); return; }int m = GetMid(l, r);Build(lson);Build(rson);PushUp(rt);}void Update(int L, int R, int val, int l, int r, int rt) {if (L <= l && r <= R) {Sum[rt] += ((r - l + 1)*val);Mark[rt] += val;return;}PushDown(rt, (r - l + 1));int m = GetMid(l, r);if (L <= m) Update(L, R, val, lson);if (m < R) Update(L, R, val, rson);PushUp(rt);}int64 Query(int L, int R, int l, int r, int rt) {if (L <= l && r <= R) {return Sum[rt];}PushDown(rt, (r - l + 1));int64 ans = 0;int m = GetMid(l, r);if (L <= m) ans += Query(L, R, lson);if (m < R) ans += Query(L, R, rson);return ans;}int main(){//freopen("input.txt", "r", stdin);//freopen("output.txt", "w", stdout);while (~scanf("%d %d", &N, &Q)) {Build(1, N, 1);char str[2];int L, R, c;while (Q--) {scanf("%s %d %d", str, &L, &R);if ('C' == str[0]) {scanf("%d", &c);if (0 == c) { continue; }Update(L, R, c, 1, N, 1);}else { printf("%I64d\n", Query(L, R, 1, N, 1)); }}}return 0;}
0 0
原创粉丝点击