POJ 3468 A Simple Problem with Integers

线段树的指针表示法。

代码还有待消化。。

 

代码里面多次用到了函数递归,感觉这次对递归又有了深一层的理解。

  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 }
代码君

 

posted @ 2014-07-15 15:43  AOQNRMGYXLMV  阅读(161)  评论(2编辑  收藏  举报