线段树的指针表示法。
代码还有待消化。。
代码里面多次用到了函数递归,感觉这次对递归又有了深一层的理解。
1 #define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 using namespace std; 6 7 struct CNode 8 { 9 int L, R; 10 CNode *pLeft, *pRight; 11 long long nSum; 12 long long Inc; 13 }; 14 CNode Tree[200000 + 10]; //2倍叶子节点就够 15 int nCount = 0; 16 int Mid(CNode *pRoot) 17 { 18 return (pRoot->L + pRoot->R) / 2; 19 } 20 21 void BuildTree(CNode *pRoot, int L, int R) 22 { 23 pRoot->L = L; 24 pRoot->R = R; 25 pRoot->nSum = 0; 26 pRoot->Inc = 0; 27 if(L == R) 28 return; 29 ++nCount; 30 pRoot->pLeft = Tree + nCount; 31 ++nCount; 32 pRoot->pRight = Tree + nCount; 33 BuildTree(pRoot->pLeft, L, (L+R)/2); 34 BuildTree(pRoot->pRight, (L+R)/2 + 1, R); 35 } 36 37 void Insert(CNode *pRoot, int i, int v) 38 { 39 if(pRoot->L == i && pRoot->R == i) 40 { 41 pRoot->nSum = v; 42 return; 43 } 44 pRoot->nSum += v; 45 if(i <= Mid(pRoot)) 46 Insert(pRoot->pLeft, i, v); 47 else 48 Insert(pRoot->pRight, i ,v); 49 } 50 51 void Add(CNode *pRoot, int a, int b, long long c) 52 { 53 if(pRoot->L == a && pRoot->R == b) 54 { 55 pRoot->Inc += c; 56 return; 57 } 58 pRoot->nSum += (b - a + 1) * c; 59 if(b <= (pRoot->L + pRoot->R)/2) 60 Add(pRoot->pLeft, a, b, c); 61 else if(a >= (pRoot->L + pRoot->R)/2 + 1) 62 Add(pRoot->pRight, a, b, c); 63 else 64 { 65 Add(pRoot->pLeft, a, (pRoot->L + pRoot->R)/2, c); 66 Add(pRoot->pRight, (pRoot->L + pRoot->R)/2 + 1, b, c); 67 } 68 } 69 70 long long QuerynSum(CNode *pRoot, int a, int b) 71 { 72 if(pRoot->L == a && pRoot->R == b) 73 return pRoot->nSum + 74 (pRoot->R - pRoot->L + 1) * pRoot->Inc; 75 76 pRoot->nSum += (pRoot->R - pRoot->L + 1) * pRoot->Inc; 77 Add(pRoot->pLeft, pRoot->L, Mid(pRoot), pRoot->Inc); 78 Add(pRoot->pRight, Mid(pRoot) + 1, pRoot->R, pRoot->Inc); 79 pRoot->Inc = 0; 80 if(b <= Mid(pRoot)) 81 return QuerynSum(pRoot->pLeft, a, b); 82 else if(a >= Mid(pRoot) + 1) 83 return QuerynSum(pRoot->pRight, a, b); 84 else 85 { 86 return QuerynSum(pRoot->pLeft, a, Mid(pRoot)) + 87 QuerynSum(pRoot->pRight, Mid(pRoot) + 1, b); 88 } 89 } 90 91 int main(void) 92 { 93 #ifdef LOCAL 94 freopen("3468in.txt", "r", stdin); 95 #endif 96 97 int n, q, a, b, c; 98 char cmd[10]; 99 scanf("%d%d", &n, &q); 100 int i, j, k; 101 nCount = 0; 102 BuildTree(Tree, 1, n); 103 for (i = 1; i <= n; ++i) 104 { 105 scanf("%d", &a); 106 Insert(Tree, i, a); 107 } 108 for(i = 0; i < q; ++i) 109 { 110 scanf("%s", cmd); 111 if(cmd[0] == 'C') 112 { 113 scanf("%d%d%d", &a, &b, &c); 114 Add(Tree, a, b, c); 115 } 116 else 117 { 118 scanf("%d%d", &a, &b); 119 printf("%I64d\n", QuerynSum(Tree, a, b)); 120 } 121 } 122 123 return 0; 124 }