鏈接二
解法線段樹,線段樹有些像是特殊的二叉平衡樹,不知道的可以搜搜二叉平衡樹,可能並沒有你想象中的那樣難。
AC代碼:
#include <stdio.h>
#include <stdlib.h>
struct node{
int data, min, max, mid;//由min、max得到mid,小於mid的部分在左子樹,大於mid的部分都在右子樹。
node *leftchild, *rightchild;//左右子節點。
};
typedef node * nodePoint;
nodePoint CreateTree(int l, int r) {
nodePoint newNode = (nodePoint)malloc(sizeof(node));
//if(newNode == NULL)
newNode->min = l;
newNode->max = r;
newNode->leftchild = NULL;
newNode->rightchild = NULL;
newNode->data = 0;//初始化數據。
int m = (l+r)/2;
newNode->mid = m;
if(m >= l && l != r) newNode->leftchild = CreateTree(l, m);//如果沒有&&l!=r這個條件,m==l且l==r時將是死循環。
if(m < r) newNode->rightchild = CreateTree(m+1, r);
return newNode;
}
void addData(nodePoint ct, int n, int d) {
while(ct->min < ct->max) {
ct->data += d;//從跟節點到目標葉節點路徑都加上d
if(n <= ct->mid) ct = ct->leftchild;
else ct = ct->rightchild;
}
ct->data += d;
}
int queryData(nodePoint ct, int i, int j) {
if(ct->min == i && ct->max == j) return ct->data;
if(i > ct->mid) return queryData(ct->rightchild, i, j);//要詢問的區間在右子樹。
if(j <= ct->mid) return queryData(ct->leftchild, i, j);
return queryData(ct->leftchild, i, ct->mid)+queryData(ct->rightchild, ct->mid+1, j);//要詢問的區間包含mid時。
}
int main() {
int n, m, x, i;
char str[9];
scanf("%d%d", &n, &m);
nodePoint Tree = CreateTree(1,n);
for(i = 1; i <= n; i++) {
scanf("%d", &x);
addData(Tree, i, x);
}
while(m--) {
scanf("%s%d%d", str, &i, &x);
if(str[0] == 'A') addData(Tree, i, x);
else printf("%d\n", queryData(Tree, i, x));
}
return 0;
}
---BY HYK--