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

 

你可能感兴趣的:(Integer)