题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=14797
题意:给定一些点的值,并在操作的过程中会附带一些重新赋值的操作。问某个区间内最大值是多少。
思路:线段树。轻松愉快不解释。
源码:
#include <cstdio>
#include <cmath>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n,m;
int const MAXN = 200000;
int sum[MAXN<<2];
int gmax(int a,int b)
{
return a>b?a:b;
}
void update(int a,int now,int L,int R,int st)
{
if(L==R){
sum[st] = now;
return;
}
int mid = (L+R)>>1;
if(mid>=a) update(a,now,L,mid,st<<1);
else if(mid<a) update(a,now,mid+1,R,(st<<1)+1);
sum[st] = gmax(sum[st<<1],sum[(st<<1)+1]);
// puts(" hahah\n");
}
int query(int l,int r,int L,int R,int st)
{
if(l<=L && r>=R){
return sum[st];
}
int mid = (L+R)>>1;
int t1=0,t2=0;
if(mid>=l) t1 = query(l,r,L,mid,st<<1);
if(mid<r) t2 = query(l,r,mid+1,R,(st<<1)+1);
return gmax(t1,t2);
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
int a,b;
char t[5];
memset(sum,0,sizeof(sum));
for(int i=1; i<=n; i++){
scanf("%d",&a);
update(i,a,1,n,1);
}
for(int i=0; i<m; i++){
scanf("%s%d%d",t,&a,&b);
if(t[0]=='Q') printf("%d\n",query(a,b,1,n,1));
if(t[0]=='U') update(a,b,1,n,1);
}
}
return 0;
}