本文出自:svitter的blog ——尽管刷了很多水题,我依然在很浅的地方沉了
题意
线段树,要求求区间最大值。
算法
不用优化很多,递归求解就过了。 注意i从0开始,查询时区间的划分,还有i <= mid()的等号
AC代码
//author: svtter
//
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <map>
#include <algorithm>
#include <queue>
#include <cmath>
#define INF 0xffffff
#define lln long long
#ifdef ONLINE_JUDGE
#define FOI(file) 0
#define FOW(file) 0
#else
#define FOI(file) freopen(file,"r",stdin);
#define FOW(file) freopen(file,"w",stdout);
#endif
using namespace std;
struct CNode
{
int l, r;
int max;
int mid()
{
return (l+r)/2;
}
};
CNode tree[600011];
void BuildTree(int root, int l, int r)
{
tree[root].l = l;
tree[root].r = r;
tree[root].max = -INF;
if(l != r)
{
BuildTree(root*2, l , (l+r)/2);
BuildTree(root*2+1, (l+r)/2+1, r);
}
}
void Insert(int root, int i, int v)
{
if(tree[root].l == tree[root].r)
{
tree[root].max = v;
return;
}
tree[root].max = max(tree[root].max, v);
if(i <= tree[root].mid())
Insert(root*2, i, v);
else
Insert(root*2+1, i, v);
}
int Query(int root, int l, int r)
{
if(tree[root].l == l && tree[root].r == r)
return tree[root].max;
if(r <= tree[root].mid())
return Query(root*2, l, r);
else if(l > tree[root].mid())
return Query(root*2+1, l, r);
else
return max(Query(root*2, l, tree[root].mid()),
Query(root*2+1, tree[root].mid()+1, r));
}
int Update(int root, int i, int v)
{
if(tree[root].l == tree[root].r)
return tree[root].max = v;
if(i <= tree[root].mid())
return tree[root].max = max(Update(root*2, i, v), tree[root*2+1].max);
else
return tree[root].max = max(Update(root*2+1, i, v), tree[root*2].max);
}
int main()
{
FOI("input");
//FOW("output");
//write your programme here
int n, m, t;
int i, j;
int ans;
char ch[10];
while(~scanf("%d%d", &n, &m))
{
BuildTree(1,1,n);
for(i = 1; i <= n; i++)
{
scanf("%d", &t);
Insert(1, i, t);
}
for(i = 0; i < m ;i++)
{
scanf("%s", ch);
if(ch[0] == 'U')
{
scanf("%d%d", &t, &j);
Update(1, t, j);
}
else
{
scanf("%d%d", &t, &j);
ans = Query(1, t, j );
printf("%d\n", ans);
}
}
}
return 0;
}