您的位置:首页 > 其它

HDU 1754 线段树

2014-07-12 15:29 267 查看
//线段树 HUD 1754
//http://acm.hdu.edu.cn/showproblem.php?pid=1754
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int Maxn = 200002;

typedef struct //结构体用来建立数线段树,保存左右叶子以及区间的最大值
{
int Max;
int left, right;
} NODE;

int n, m;
int num[Maxn];
NODE tree[Maxn*20];

int build(int root, int left, int right)//建立线段树
{
int mid;
tree[root].left = left;//当前节点表示的区间
tree[root].right = right;
if(left == right)//若左右区间相同,那么此时的最大值就是root所对应的num[root]的值
return tree[root].Max = num[left];
mid = (left+right)/2;//去中间点
int a, b;
a = build(root*2,left,mid);//当前左子树在细分
b = build(root*2+1,mid+1,right);//当前右子树在细分
return tree[root].Max = max(a,b);//返回当前子树的最大值并储存在tree[root].Max中
}

int find_(int root, int left, int right)//查找从letf到right之间的最大值
{
if(left>tree[root].right || tree[root].left>right)//若所给的区间不在该子树的区间内,返回0
return 0;
if(left<=tree[root].left && tree[root].right<=right)//若所给的区间包含了该子树的区间,返回该子树的最大值
return tree[root].Max;
int a, b;
a = find_(root*2,left,right);//当前左子树细分查找
b = find_(root*2+1,left,right);//当前右子树细分查找
return max(a,b);//返回当前子树的最大值
}

int updata(int root, int x, int y)//更新某点的值
{
if(x<tree[root].left || tree[root].right<x)//若该点不在当前子树的区间内,就返回当前子树的最大值
return tree[root].Max;
if(tree[root].left==x && tree[root].right==x)//当该点恰好和当前子树区间相同时,当前子树的最大值就更新为给定的数y
return tree[root].Max = y;//并返回最大值
int a, b;
a = updata(root*2,x,y);
b = updata(root*2+1,x,y);
return tree[root].Max = max(a,b);//返回当前子树的最大值
}

int main()
{
char c;
int x, y;
while(cin >> n >> m)
{
for(int i = 1; i <= n; i++)
cin >> num[i];
build(1,1,n);//建立线段树
while(m--)
{
cin >> c >> x >> y;
if(c == 'Q')
{
cout << find_(1,x,y) << endl;
}
if(c == 'U')
{
num[x] = y;
updata(1,x,y);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: