/** \brief
* 求线段树某个区间的最大值
*/
#include
int max[100];
void Build(int lift, int right, int rt);
void updata(int point, int x, int lift, int right, int rt);
int query(int L, int R, int lift, int right, int rt);
int main()
{
int lift, right;
printf("输入你要构建的范围: ");
scanf("%d%d", &lift, &right);
Build(lift, right, 1);
int point, x;
printf("请输入你要更新的点和更新的数: ");
scanf("%d%d", &point, &x);
updata(point, x, lift, right, 1);
int L, R;
printf("请输入你要查找的区间: ");
scanf("%d%d", &L, &R);
printf("%d\n", query(L, R, lift, right, 1));
return 0;
}
void Build(int lift, int right, int rt)
{
if (lift == right) {
scanf("%d", &max[rt]);
return ;
}
int m = (lift + right) / 2;
Build(lift, m, rt*2); // 构建左儿子
Build(m+1, right, rt*2+1); // 构建右儿子
max[rt] = max[rt*2] > max[rt*2+1] ? max[rt*2]: max[rt*2+1];
}
// 实现单点替换为 x; 替换的点为 point;
void updata(int point, int x, int lift, int right, int rt)
{
if (lift == right) {
max[rt] = x;
return ;
}
int m = (lift + right) / 2;
if (point <= m)
updata(point, x, lift, m, rt*2); // 向左寻找
else
updata(point, x, m+1, right, rt*2+1); // 向右寻找
// 已经找完之后, 再更新上面的点;
max[rt] = max[rt*2] > max[rt*2+1] ? max[rt*2]: max[rt*2+1];
}
// 函数返回某个区间段上的最大值;
int query(int L, int R, int lift, int right, int rt)
{
int Max(int x, int y);
int ret = 0;
// 函数的基准: 找到一个完全被 L R包含的范围(且是兄弟子叶——同父亲);
if (lift >= L && right <= R)
return max[rt];
int m = (lift + right) / 2;
if (L <= m) // 向左传递
ret = Max(ret, query(L, R, lift, m, rt*2));
if (R > m)
ret = Max(ret, query(L, R, m+1, right, rt*2+1));
return ret;
}
int Max(int x, int y)
{
return x > y ? x: y;
}