您的位置:首页 > 其它

hdu 1754 线段树

2010-02-10 15:36 417 查看

I Hate It

Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3375 Accepted Submission(s): 1123

Problem Description
很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。
这让很多学生很反感。

不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。



Input
本题目包含多组测试,请处理到文件结束。
在每个测试的第一行,有两个正整数 N 和 M ( 0<N<=200000,0<M<5000 ),分别代表学生的数目和操作的数目。
学生ID编号分别从1编到N。
第二行包含N个整数,代表这N个学生的初始成绩,其中第i个数代表ID为i的学生的成绩。
接下来有M行。每一行有一个字符 C (只取'Q'或'U') ,和两个正整数A,B。
当C为'Q'的时候,表示这是一条询问操作,它询问ID从A到B(包括A,B)的学生当中,成绩最高的是多少。
当C为'U'的时候,表示这是一条更新操作,要求把ID为A的学生的成绩更改为B。




Output
对于每一次询问操作,在一行里面输出最高成绩。



Sample Input

5 6
1 2 3 4 5
Q 1 5
U 3 6
Q 3 4
Q 4 5
U 2 9
Q 1 5





Sample Output

5
6
5
9

典型的线段树,不要忘记U改变成绩时update最高成绩。

#include<iostream>
using namespace std;
#define Max 200010
#define max(a,b) (a>b?a:b)

struct node
{
	int l,r;
	int highest;
	struct node *lchild,*rchild;
};
node mem[400010];
int pos;
int score[Max];
node *new_tree()
{
	node *pt=&mem[pos++];
	memset(pt,0,sizeof(pt));
	return pt;
}

node *create(int il,int ir)
{
	node* root=new_tree();
	root->l=il;
	root->r=ir;
	if(ir-il>1)
	{
		int mid=(il+ir)/2;
		root->lchild=create(il,mid);
		root->rchild=create(mid,ir);
		root->highest=max(root->lchild->highest,root->rchild->highest);
	}
	else
		root->highest=max(score[root->l],score[root->r]);
	return root;
}

void update(node* now,int id)
{
	if(now->r-now->l==1)
	{
		now->highest=max(score[now->l],score[now->r]);
		return ;
	}
	if(now->lchild->r>=id)
		update(now->lchild,id);
	if(now->rchild->l<=id)
		update(now->rchild,id);
	now->highest=max(now->lchild->highest,now->rchild->highest);
	return ;
}

int search(node *now,int il,int ir)
{
	if(now->l==il&&now->r==ir)
	{
		return now->highest;
	}
	int mid=(now->l+now->r)/2;
	if(il>=mid)
		return search(now->rchild,il,ir);
	if(ir<=mid)
		return search(now->lchild,il,ir);
	else
	{
		int temp1=search(now->lchild,il,mid);
		int temp2=search(now->rchild,mid,ir);
		return max(temp1,temp2);
	}
}

int main()
{
	node* root;
	char ch;
	int m,n,i,id1,id2;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		pos=0;
		for(i=1;i<=n;i++)
			scanf("%d",&score[i]);
		root=create(1,n);
		getchar();
		while(m--)
		{
			ch=getchar();
			scanf("%d%d",&id1,&id2);
			getchar();
			if(ch=='Q')
			{
				if(id1==id2)
					printf("%d/n",score[id1]);
				else printf("%d/n",search(root,id1,id2));
			}
			else
			{
				score[id1]=id2;
				update(root,id1);
			}
		}
	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: