HDU 1754_I Hate It

【题意】给定区间求最大值

【分析】线段树单点更新

【代码】

#include<cstdio>
#include<iostream>
using namespace std;
const int maxn=1<<21;
const int INF=0x3fffffff;
int Max=0;
int mid;
struct Node
{
    int l,r;//左孩子,右孩子
    int value;
}N[maxn];
int p[200005];//记录标号
void build(int i,int left ,int right)//区间[left,right],节点标号i
{
    N[i].l=left;
    N[i].r=right;
    N[i].value=0;
    if(left==right)
    {
        p[left]=i;
        return;
    }
    mid=(left+right)>>1;
    build(i<<1,left,mid);
    build(1+(i<<1),mid+1,right);
}
void update(int i)//从下往上更新单节点
{
    if(i==1) return ;
    int pi=i/2;
    int left=pi<<1;
    int right=(pi<<1)+1;
    N[pi].value=max(N[left].value,N[right].value);
    update(i/2);
}
void query(int i,int left,int right)//从上往下查询节点
{
    if(N[i].l==left&&N[i].r==right)
    {
        Max=max(N[i].value,Max);
        return;
    }
    i<<=1;
    if(N[i].r>=left&&N[i].r>=right) query(i,left,right);
    else if(N[i].r>=left&&N[i].r<=right) query(i,left,N[i].r);
    i++;
    if(N[i].l<=right&&N[i].l<=left) query(i,left,right);
    else if(N[i].l<=right&&N[i].l>=left) query(i,N[i].l,right);
}
int main (void)
{
    int n,m;
    int A,B;
    char c[2];
    while(scanf("%d%d",&n,&m)==2)
    {
         build(1,1,n);
        for(int i=1;i<=n;i++)
        {
             scanf("%d",& N[p[i]].value);
             update(p[i]);
        }
        for(int i=1;i<=m;i++)
        {
            scanf("%s%d%d",c,&A,&B);
            if(c[0]=='Q')
            {
                Max=0;
                query(1,A,B);
                printf("%d
",Max);
            }
            else
            {
                N[p[A]].value=B;
                update(p[A]);
            }
        }
    }
    return 0;
}


原文地址:https://www.cnblogs.com/Tuesdayzz/p/5758861.html