您的位置:首页 > 其它

HDU 1754 I Hate It(线段树入门,单点更新求最值)

2018-02-07 12:01 375 查看
B - I Hate It 
      HDU - 1754
用线段树模板,就能过这道题,这道题和“敌兵布阵”不一样的地方在于他是要求区间最大值,和区间求和非常相似,代码基本都通用,可惜一直忘了用getchar()吸收回车,输入字符的时候错了n遍,但是总体来说还是很简单的一道入门题
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<cmath>
using namespace std;
#define maxn 200005
int sum[maxn << 2];
int n;
void pushup(int rt)
{
sum[rt] = max(sum[rt << 1], sum[(rt << 1) | 1]);
}
void build(int l, int r, int rt)
{
if(l == r)
{
scanf("%d",&sum[rt]);
return ;
}
int m = (l + r) >> 1;
build(l, m, rt << 1);
build(m + 1, r, (rt << 1) | 1);
pushup(rt);
}

void update(int p, int add, int l, int r,int rt)
{
if(l == r)
{
sum[rt] = add;
return ;
}
int m = (l + r) >> 1;
if(p <= m)update(p, add, l, m, rt << 1);
else update(p, add, m + 1, r, (rt << 1) | 1);
pushup(rt);
}
int query(int left, int right, int l, int r, int rt)
{
if(left <= l && right >= r)return sum[rt];
int m = (l + r) >> 1;
int ans = 0;
if(left <= m)ans =max(ans, query(left, right, l, m, rt << 1));
if(right > m)ans =max(ans, query(left, right, m + 1, r, (rt << 1) | 1));
return ans;
}
int main()
{

int m, n;
int x, y;
char a;
while(scanf("%d%d",&n,&m)!=EOF)

{
//memset(sum, 0, sizeof(sum));
build(1, n, 1);
while(m --)
{
getchar();
scanf("%c",&a);
scanf("%d%d",&x,&y);
if(a == 'Q')
{
int ans = query(x, y, 1, n, 1);
printf("%d\n",ans);
}
if(a == 'U')
{
update(x, y, 1, n, 1);
}

}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: