题目描述
N个学生,M个操作,操作分两种,Q:询问A到B中值最大的是多少;S:将A更改为B。
解题思路
数据范围过大,暴力肯定撞墙,线段树问题,单点更新求区间最大值,线段树的入门模板题。
代码部分
#include <iostream>
#include <stdio.h>
#include <algorithm>
#define lc left, mid, root << 1
#define rc mid + 1, right, root << 1 | 1
using namespace std;
const int maxn = 2e5 + 10;
int ma[maxn << 2];
void push_up(int root)
{
ma[root] = max(ma[root << 1], ma[root << 1 | 1]);
}
void build(int left, int right, int root)
{
if(left == right)
{
scanf("%d", &ma[root]);
return;
}
int mid = (left + right) >> 1;
build(lc);
build(rc);
push_up(root);
}
void update(int left, int right, int root, int a, int b)
{
if(left == right)
{
ma[root] = b;
return;
}
int mid = (left + right) >> 1;
if(a <= mid) update(lc, a, b);
else update(rc, a, b);
push_up(root);
}
int query(int left, int right, int root, int a, int b)
{
if(a <= left && right <= b)
{
return ma[root];
}
int mid = (left + right) >> 1;
int ans = 0;
if(a <= mid) ans = max(ans, query(lc, a, b));
if(b > mid) ans = max(ans, query(rc, a, b));
return ans;
}
int main()
{
int n, m, a, b;
char c;
while(~scanf("%d%d", &n, &m))
{
build(1, n, 1);
while(m --)
{
scanf(" %c %d%d", &c, &a, &b);
if(c == 'Q')
{
int ans = query(1, n, 1, a, b);
printf("%d\n", ans);
}
else
{
update(1, n, 1, a, b);
}
}
}
return 0;
}