nyoj116士兵殺敵2

題目鏈接:士兵殺敵2
鏈接二

解法線段樹,線段樹有些像是特殊的二叉平衡樹,不知道的可以搜搜二叉平衡樹,可能並沒有你想象中的那樣難。

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--
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章