题目链接
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;
}
京公网安备 11010502036488号