Hdu 1754【線分樹】

2626 ワード

/*I Hate It 
Time Limit : 9000/3000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 0   Accepted Submission(s) : 0
Font: Times New Roman | Verdana | Georgia 
Font Size: ← →
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

Hint
Huge input,the C function scanf() will work better than cin 
Author
linle 
Source
2007        (6)_linle   
*/ 
#include<stdio.h>
int segtree[800001], n, m, data[200010], max;
int Max(int a, int b)
{
	return a>b?a:b;
}
void build_segtree(int l, int r, int rt)
{
	if(l == r)
	{ 
		scanf("%d", &segtree[rt] );//leaf num
		return ;
	}
	int k = (l + r)>>1; //save time
	build_segtree(l, k, rt<<1);
	build_segtree(k + 1,  r, rt<<1|1);
	segtree[rt] = Max(segtree[rt<<1], segtree[rt<<1|1]);//back
}
void update(int a, int b, int l, int r, int rt)
{
	if(l ==  r)
	{
		segtree[rt] = b;
		return ;
	}
	int k = (l+r)>>1;//save time
	if(a <= k)
	update(a, b, l, k, rt<<1);
	else 
	update(a, b, k + 1, r, rt<<1|1);
	segtree[rt] = Max(segtree[rt<<1], segtree[rt<<1|1]);//back
}
int question(int a, int b, int l , int r, int rt)
{
	if(a <= l && r <= b)//visit 
	{
		return segtree[rt];
	}
	int sum = 0, k = (l+r)>>1;
	if( a <= k)//the left part
	sum = Max(sum, question( a, b, l , k, rt<<1) );
	if(b > k )//the right part
	sum = Max(sum, question( a, b, k+1, r, rt<<1|1) );
	return sum;
}
int main()
{
	int i , j, a, b;
	char ch;
	while(scanf("%d%d", &n, &m) != EOF)
	{
		build_segtree( 1 , n , 1 );
		for(i = 0; i < m; ++i)
		{
			getchar();
			scanf("%c%d%d", &ch, &a, &b);
			if(ch == 'U')//update
			{
				update(a, b, 1, n, 1);//update the segtree 
			}
			else
			{
				printf("%d
", question(a , b , 1, n, 1) ); } } } return 0; }

标题:標準の線分ツリーで、ポイント更新と区間クエリの最大値が主な操作です.
考え方:セグメントツリーテンプレート.
注意:ここには穴があいています.Maxはマクロで定義しないで、関数で作ってください.そうしないとタイムアウトします.の(関数呼び出しパラメータは計算済みで、一度だけ計算されます.マクロ定義は計算されず、実行時に毎回計算されます.)