hdu 1754 线段树 注意线段树节点的设计 求什么,设什么
#include <iostream>
#include <cstdio>
using namespace std;
const int MAXN=2000000;
int n,m,a[MAXN+5];
struct tree
{
int l,r;
int v;
}trees[MAXN*2];
int max(int k,int l)
{
return k>l?k:l;
}
void buildtree(int rs,int l,int r)
{
//printf("%d %d %d\n",rs,l,r);
trees[rs].l=l;
trees[rs].r=r;
if(r==l)
{
trees[rs].v=a[l];
return ;
}
int mid=(l+r)/2;
buildtree(rs*2,l,mid);
buildtree(rs*2+1,mid+1,r);
trees[rs].v=max(trees[rs*2].v,trees[rs*2+1].v);
}
void update(int rs,int k,int l)
{
//printf("%d %d %d %d %d\n",rs,k,l,trees[rs].l,trees[rs].r);
if(trees[rs].l==k&&trees[rs].r==k)
{
trees[rs].v=l;
return ;
}
int mid=(trees[rs].l+trees[rs].r)/2;
if(k<=mid)update(rs*2,k,l);
if(k>mid)update(rs*2+1,k,l);
trees[rs].v=max(trees[rs*2].v,trees[rs*2+1].v);
}
int querry(int rs,int l,int r)
{
//printf("%d %d %d\n",rs,l,r);
if(trees[rs].l==l&&trees[rs].r==r)
return trees[rs].v;
int mid=(trees[rs].l+trees[rs].r)/2;
if(r<=mid)return querry(rs*2,l,r);
if(l>mid)return querry(rs*2+1,l,r);
if(l<=mid&&r>mid)
return max(querry(rs*2,l,mid),querry(rs*2+1,mid+1,r));
return 0;
}
int main()
{
int i,ac,bc;
char c;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
buildtree(1,1,n);
for(i=1;i<=m;i++)
{
getchar();
scanf("%c%d%d",&c,&ac,&bc);
if(c=='Q')
printf("%d\n",querry(1,ac,bc));
else
update(1,ac,bc);
}
}
return 0;
}
做的第一个线段树,注意建树时,r,l值的确定,还有就是更新和查询时的mid值确定,思路一定要清晰

浙公网安备 33010602011771号