题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=1754

解题思路

区间访问,单点修改。
算是个板子题,所以没有题解。
里面有大佬讲解线段树
我觉得线段树入门的话,说实话就一个板子,如果能自己敲出来说明入门了;
怎么入门?开始第一次学的时候,学了两天还是不能理解,即使理解了也只看到了皮毛,勉强背过板子,但其实是真的没有理解什么是线段树,要如何实现;
但是从那次学完之后,我就把线段树扔在脑后一个月,这次又拿起来一看,感觉大彻大悟,在没有看板子的情况下,直接猛敲,还是很爽的;
我这么说的就是希望如果一时不能理解某些东西,我们这种小白不要太着急,时间会沉淀知识的!

AC代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long

using namespace std;
const int N=2e5+10;
const int inf=0x3f3f3f3f;

int n,m,stu[N],tree[N<<2],a,b;
char op;

void Build(int l,int r,int i)
{
    if(l==r) 
    {
        tree[i]=stu[l];
        return ;    
    }
    int mid=(l+r)>>1;
    Build(l,mid,i<<1);
    Build(mid+1,r,i<<1|1);
    tree[i]=max(tree[i<<1],tree[i<<1|1]);
    return ;
}
void Update(int l,int r,int i,int x,int y)
{
    if(l==r) 
    {
        tree[i]=y;
        return ;
    }
    int mid=(l+r)>>1;
    if(x>mid) Update(mid+1,r,i<<1|1,x,y);//right subtree
    else Update(l,mid,i<<1,x,y);//left subtree
    tree[i]=max(tree[i<<1],tree[i<<1|1]);
    return ;
}
int Query(int l,int r,int i,int x,int y)
{
    int res=-inf;
    if(x<=l && r<=y)
    return tree[i];
    if(x>r || y<l) return 0;
    int mid=(l+r)>>1;
    if(x<=mid) res=max(res,Query(l,mid,i<<1,x,y));//left subtree
    if(y>mid) res=max(res,Query(mid+1,r,i<<1|1,x,y));//right subtree
    return res;    
}

int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        memset(tree,0,sizeof tree);
        for(int i=1;i<=n;i++)
        scanf("%d",&stu[i]);
        Build(1,n,1);
        while(m--)
        {
            cin>>op>>a>>b;
            if(op=='Q')
            printf("%d\n",Query(1,n,1,a,b));
            else
            Update(1,n,1,a,b);
        }
    }    
    return 0;
}