/*
线段树学习:如果一个节点为i,那么他的左孩子为2I+1,右孩子为2i+2;
*/
#include<stdio.h>
#define min(a,b) a<b?a:b;
int tree[100];
int a[100] = {2,5,1,4,9,3};
//创建树
void create(int root, int c[], int start, int end) {//root表示当前线段树下标
//a表示用来构造线段树的数组
//star表示数组起始位置
//end表示数组末尾位置
if (start == end) {
//叶子节点
tree[root] = c[start];
}
else {
int mid = (start + end) / 2;
create(root * 2 + 1, a, start, mid);//构造左子树
create(root * 2 + 2, a, mid+1, end);//构造右子树
tree[root] = min(tree[root * 2 + 1], tree[root * 2 + 2]);//节点保存最小值
}
}
//线段树区间查询,查询最小值
int find(int root, int starti, int endi, int start, int end) {
if (starti > end || endi < start) {
return 65535;//无法查询到
}
if (starti <=start&&endi >= end) {
return tree[root];
}
int mid = (start + end) / 2;
return min(find(root * 2 + 1, starti, endi, start, mid),find(root*2+2,starti,endi,mid+1,end));
}
//节点更新,节点的更新势必会影响到其父节点的更新,所以更新了节点之后还得更新其父节点
void update(int root, int start, int end, int index, int num) {
//root表示树状数组根节点下标
//start区间其实下标
//end区间结尾下标
//index需要更新的结点在原数组中的的下标
//num更新的数值,假设加上num
if (start == end) {
//叶子节点
if (start == index) {
//判断是否是需要跟新的结点
tree[root] += num;
}
}
else {
int mid = (start + end) / 2;
if (index <= mid) {
//二分,如果小于mid则只在左子树查找
update(root * 2 + 1, start, mid, index, num);
}
else {
update(root * 2 + 2, mid + 1, end, index, num);
}
tree[root] = min(tree[root * 2 + 1], tree[root * 2 + 2]);
}
}
int main() {
create(0, a, 0,5);
int x, y;
int index, number;
//情书如你要跟新的坐标和数值
scanf("%d %d", &index, &number);
update(0, 0, 5, index, number);
while (~scanf("%d %d", &x, &y)) {
printf("%d\n", find(0, x, y, 0,5));
}
return 0;
}