——我大C++的指针岂是尔等能够简单领悟!
给N,Q,然后跟操作。注意判断Q,C使用scanf("%s")。
测试数据:
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
4
55
9
15
线段树基础题目,但是在其上添加了区间加和操作,增加了难度。 如果每个节点直接更新肯定是不行的,可以保存sum,inc(增量)来进行计算。 如果区间正好对应,那么将this.inc += inc。如果区间不是直接对应的,那么sum值增加inc×增加的个数。 之后在进行查询的同时,如果inc的值不是0,可以代入到下一层的inc中,本sum += inc×节点个数。
处理指针的时候出现了些问题,没有写L == R的情况溢出。还有就是r <= mid的情况也没有留意,也造成溢出问题。
最后的问题就是sum一开始忘记inc×个数,直接导致多次WA。
还有就是i从1开始,树状数组也是。
//author: svtter // #include <iostream> #include <stdio.h> #include <string.h> #include <vector> #include <map> #include <algorithm> #include <queue> #include <cmath> #define INF 0xffffff #define lln long long #ifdef ONLINE_JUDGE #define FOI(file) 0 #define FOW(file) 0 #else #define FOI(file) freopen(file,"r",stdin); #define FOW(file) freopen(file,"w",stdout); #endif using namespace std; struct CNode { int L, R; CNode *pLeft, *pRight; lln sum; lln inc; int mid() { return (L+R)/2; } }; #define N 300000 CNode tree[N]; int c = 0; void BuildTree(CNode *root, int l, int r) { root->L = l; root->R = r; root->sum = 0; root->inc = 0; //没写 if(l == r) return; c ++; root->pLeft = tree+c; c ++; root->pRight = tree+c; if(l != r) { BuildTree(root->pLeft, l, (l+r)/2); BuildTree(root->pRight,(l+r)/2+1, r); } } void Insert(CNode *root, int i, int val) { if(root->L == root->R) { root->sum = val; return; } root->sum += val; if(i <= root->mid()) Insert(root->pLeft, i, val); else Insert(root->pRight, i, val); } void Add(CNode *root, int l, int r, lln inc) { if(root->L == l && root->R == r) { root->inc += inc; return; } root->sum += inc *(r-l+1); if(r <= root->mid()) Add(root->pLeft, l, r, inc); else if(l > root->mid()) Add(root->pRight, l, r, inc); else { Add(root->pLeft, l, root->mid(), inc); Add(root->pRight, root->mid()+1, r, inc); } } lln Query(CNode *root, int l, int r, lln inc) { if(root->L == l && root->R == r) return root->sum + (root->inc+inc) * (r-l+1); if(r <= root->mid()) return Query(root->pLeft, l, r, root->inc+inc); else if(l > root->mid()) return Query(root->pRight,l, r, root->inc+inc); else { return Query(root->pLeft, l, root->mid(), root->inc+inc) + Query(root->pRight, root->mid()+1, r, root->inc+inc); } } int main() { FOI("input"); //FOW("output"); //write your programme here int n, q, m; int i, j, k; int t; char ch[10]; lln ans; CNode *root; scanf("%d%d", &n ,&q); root = tree; c = 0; BuildTree(root, 1, n); for(i = 1; i <=n ;i++) { scanf("%d", &t); Insert(root, i, t); } for(i = 0; i < q; i++) { scanf("%s", ch); if(ch[0] == 'Q') { scanf("%d%d", &j, &k); ans = Query(root, j, k, 0); printf("%lld\n", ans); } else { scanf("%d%d%d", &j, &k, &m); Add(root, j, k, m); } } return 0; }
POJ3468__A Simple Problem with Integers (线段树),布布扣,bubuko.com
POJ3468__A Simple Problem with Integers (线段树)
原文地址:http://blog.csdn.net/svitter/article/details/38400585