hdu 1754 I Hate It(单点更新)

有两种操作,更新某个人的成绩,查询区间里的最大值。

直接更新到叶子结点,在线段树的每个结点里保留一个mx表示这个区间[lft,rht]里的最大值,每次从叶子结点里更新回来记得更新路径上的mx。

/*代码风格更新后*/
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

#define LL(x) (x<<1)
#define RR(x) (x<<1|1)
#define MID(a,b) (a+((b-a)>>1))
#define INF (1<<30)
const int N=200005;

struct node
{
	int lft,rht,mx;
	int mid(){return MID(lft,rht);}
};

int y[N],n,m;

struct Segtree
{
	node tree[N*4];
	void build(int lft,int rht,int ind)
	{
		tree[ind].lft=lft;	tree[ind].rht=rht;
		tree[ind].mx=-INF;
		if(lft==rht) tree[ind].mx=y[lft];
		else 
		{
			int mid=tree[ind].mid();
			build(lft,mid,LL(ind));
			build(mid+1,rht,RR(ind));
			tree[ind].mx=max(tree[LL(ind)].mx,tree[RR(ind)].mx);
		}
	}
	void updata(int pos,int ind,int valu)
	{
		int lft=tree[ind].lft,rht=tree[ind].rht;
		if(lft==rht) tree[ind].mx=valu;
		else 
		{
			int mid=tree[ind].mid();
			if(pos<=mid) updata(pos,LL(ind),valu);
			else updata(pos,RR(ind),valu);
			tree[ind].mx=max(tree[LL(ind)].mx,tree[RR(ind)].mx);
		}
	}
	int query(int st,int ed,int ind)
	{
		int lft=tree[ind].lft,rht=tree[ind].rht;
		if(st<=lft&&rht<=ed) return tree[ind].mx;
		else 
		{
			int mid=tree[ind].mid();
			int mx1=-INF,mx2=-INF;
			if(st<=mid) mx1=query(st,ed,LL(ind));
			if(ed>mid) mx2=query(st,ed,RR(ind));
			return max(mx1,mx2);
		}
	}
}seg;
int main()
{
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		int a,b;
		char str[10];
		for(int i=1;i<=n;i++) scanf("%d",&y[i]);
		seg.build(1,n,1);
		while(m--)
		{
			scanf("%s %d %d",str,&a,&b);
			if(str[0]=='Q') printf("%d\n",seg.query(a,b,1));
			else seg.updata(a,1,b);
		}
	}
	return 0;
}


/*代码风格更新前*/
#include <iostream>
#include <cstdio>
using namespace std;
const int N=200005;
int y[N];
struct node
{
    int left,right,imax;
    int mid(){return left+(right-left)/2;}
};
struct Segtree
{
    node tree[N*4];
    void build(int left,int right,int r)
    {
        tree[r].left=left;  tree[r].right=right;
        if(left==right) tree[r].imax=y[left];
        else
        {
            int mid=tree[r].mid();
            build(left,mid,r*2);
            build(mid+1,right,r*2+1);
            tree[r].imax=max(tree[r*2].imax,tree[r*2+1].imax);
        }
    }
    void updata(int pos,int r,int co)
    {
        if(tree[r].left==tree[r].right) tree[r].imax=co;
        else
        {
            int mid=tree[r].mid();
            if(pos<=mid) updata(pos,r*2,co);
            else if(pos>mid) updata(pos,r*2+1,co);
            tree[r].imax=max(tree[r*2].imax,tree[r*2+1].imax);
        }
    }
    int query(int be,int end,int r)
    {
        if(be<=tree[r].left&&tree[r].right<=end) return tree[r].imax;
        else
        {
            int max1=0,max2=0,mid=tree[r].mid();
            if(be<=mid) max1=query(be,end,r*2);
            if(end>mid) max2=query(be,end,r*2+1);
            return max(max1,max2);
        }
    }
}seg;
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        char cmd[5];
        int a,b;
        for(int i=1;i<=n;i++) scanf("%d",&y[i]);
        seg.build(1,n,1);
        for(int i=0;i<m;i++)
        {
            scanf("%s %d %d",cmd,&a,&b);
            if(cmd[0]=='Q')
            {
                printf("%d\n",seg.query(a,b,1));
            }
            else
            {
                seg.updata(a,1,b);
            }
        }
    }
    return 0;
}




你可能感兴趣的:(struct,tree,cmd,query,Build)