hdu 1754

求出任意区间的最值,所以我们只要维护最值即可

很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。
这让很多学生很反感。

不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。
 

Input
本题目包含多组测试,请处理到文件结束。
在每个测试的第一行,有两个正整数 N 和 M ( 0<N<=200000,0<M<5000 ),分别代表学生的数目和操作的数目。
学生ID编号分别从1编到N。
第二行包含N个整数,代表这N个学生的初始成绩,其中第i个数代表ID为i的学生的成绩。
接下来有M行。每一行有一个字符 C (只取'Q''U') ,和两个正整数A,B。
当C为'Q'的时候,表示这是一条询问操作,它询问ID从A到B(包括A,B)的学生当中,成绩最高的是多少。
当C为'U'的时候,表示这是一条更新操作,要求把ID为A的学生的成绩更改为B。

 

Output
对于每一次询问操作,在一行里面输出最高成绩。
 

Sample Input
5 6
1 2 3 4 5
Q 1 5
U 3 6
Q 3 4
Q 4 5
U 2 9
Q 1 5


#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

#define MAX 200000+1
#define MAX_S  1000000

typedef struct node
{
 int st,en;
 int mark;
 int w;
 node (int z =0 ,int c=0,int b=0,int d=0):st(z),en(c),w(b),mark(d){}
}node;
int a[MAX];
node tree[MAX_S];
int flag=0;

int Max(int a1,int a2)
{
  if (a1 > a2) return a1;
  else return a2;
}

int build(int T,int s,int e)
{
   if (s==e)
     {
     tree[T]=node(s,e,a[flag++],0);
     return tree[T].w;
     }
   else
   {
       int mid = (s+e)>>1;
       int s1 = build(T<<1,s,mid);//这里真Max(build(T<<1,s,mid),build (T<<1|1,mid+1,e)) 
                                       //反why
       int s2 = build (T<<1|1,mid+1,e);
       tree[T] = node(s,e,Max(s1,s2),0);
       return tree[T].w;
   }
}

int Query(int T,int s,int e)
{
   if (tree[T].st > e || tree[T].en < s)
    return 0;
   if (s <= tree[T].st && e >= tree[T].en)
     return tree[T].w;
   else
    {
      return  Max(Query(T<<1,s,e) , Query(T<<1|1,s,e));
    }
}
void update(int T,int id,int pos)//修改指定点的值
{
    
   if (tree[T].st == tree[T].en)
        {
         if (tree[T].st == id)
          {
          tree[T].mark = pos;
       tree[T].w=pos;
       }
       return ;    
     }
   int mid = (tree[T].st + tree[T].en)>>1;
   if (mid >=id)
   update (T<<1,id,pos);
   else update (T<<1|1,id,pos);
   tree[T].w  = Max (tree[T<<1].w,tree[T<<1|1].w);//维护最大值
   tree[T].mark = pos;
}


int main ()
{
    std::ios::sync_with_stdio(false);
     int m,n;
  while(cin>>n>>m)
    {
      flag = 0;
     for (int i=0;i<n;++i) 
        cin>>a[i];
     build(1,1,n);
     char s;
     int n1,n2;
    while(m--)
     {
      cin>>s>>n1>>n2;
      if (s=='Q')
      {
          printf ("%d
",Query(1,n1,n2));
      }
       else
        {
          update(1,n1,n2);
        }    
     }
   }
    return 0;
}/*
5 6
1 2 3 4 5
Q 1 5
U 3 6
Q 3 4
Q 4 5
U 2 9
Q 1 5

*/
原文地址:https://www.cnblogs.com/yuluoluo/p/8047776.html