原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754
分析:简单线段树,更新点的最大值,随后更新上层区间的最值;找区间的最大值。
我的代码:
#include<stdio.h>
#define MAXN 200005
#define N 5005
int n,m;
struct Node
{
int l,r;
int max;
}segTree[4*MAXN];
int p[MAXN];
int Max(int a,int b)
{
return a>b?a:b;
}
void CreatsegTree(int index,int lef,int rig) //创建[lef,rig]的线段树。
{
segTree[index].l =lef; //一开始居然忘了写这个QAQ;
segTree[index].r=rig; //一开始居然忘了写这个QAQ;
if(segTree[index].l == segTree[index].r)
{
segTree[index].max=p[lef];
return ;
}
int mid=(lef+rig)>>1;
CreatsegTree(index<<1, lef,mid);
CreatsegTree(index<<1|1 ,mid+1,rig); //index<<1|1 等价于 index*2+1
segTree[index].max=Max(segTree[index<<1].max,segTree[index<<1|1].max);
}
void ModifyTree(int index,int k,int M) //找到[k,k],并更新此处的最大值为M。
{
// 当segTree[index].l==segTree[index].r 时要就返回。不然会一直我下搜。
if(segTree[index].l==segTree[index].r)
{
//找到[k,k]了,更新此处的最大值为M。
if(segTree[index].l==k) segTree[index].max=M;
return ;
}
int mid=(segTree[index].l+segTree[index].r)>>1;
if(k<=mid)
{
ModifyTree( index<<1,k,M);
//返回时,更新上层的最大值。
segTree[index].max=Max(segTree[index<<1].max,segTree[index<<1|1].max);
}
else
{
ModifyTree( index<<1|1,k,M);
segTree[index].max=Max(segTree[index<<1].max,segTree[index<<1|1].max);
}
}
//int ans;
int Query(int index,int a,int b) //找到[a,b]中的最大值。
{
// if(ans>segTree[index].max) return -1;
if(segTree[index].l==a&&segTree[index].r==b)
{
// ans=segTree[index].max;
return segTree[index].max;
}
if(segTree[index].l==segTree[index].r)
{
return -1;
}
int mid=(segTree[index].l+segTree[index].r)>>1;
if(b<=mid) Query( index<<1,a,b);
else if(a>mid) Query( index<<1|1,a,b);
else
{
// return ans=Max(Query(index<<1,a,mid),Query( index<<1|1,mid+1,b));
return Max(Query(index<<1,a,mid),Query( index<<1|1,mid+1,b));
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
int i;
for(i=1;i<=n;i++) scanf("%d",p+i);
CreatsegTree(1,1,n);
for(i=0;i<m;i++)
{
char str[5];
scanf("%s",str);
int a,b;
scanf("%d%d",&a,&b);
// ans=0;
switch(str[0])
{
case 'U':ModifyTree(1,a,b);break;
case 'Q': printf("%d\n",Query(1, a, b));break;
// Query(1, a, b);
// printf("%d\n",ans);break;
}
}
}
return 0;
}
总结:线段树代码的细节打的时候要仔细o(>﹏<)o