線段樹模板(點修改 ,區間查詢)

caiOJ1099題

題目描述

給出N個數,兩種操作:
1C x y:修改第x個數的值爲y

2P x y:求第x到第y個的最大值,注:x未必比y

輸入格式
第一行輸入NM0<N<=200000,0<M<5000),N表示有N個數,M表示有M個操作
下來N個數
然後是M個操作。
輸出格式
遇到P操作的時候,輸出結果。
樣例輸入
5 6
1 2 3 4 5
P 1 5
C 3 6
P 3 4
P 4 5
C 2 9
P 1 5
樣例輸出
5
6
5

9

代碼:(請不要直接拷貝哦)

#include <cstdio>  
#include <algorithm>  
int a[200005],n,m,x,y;
char ch[1];
struct TREE{
	int l,r,maxx;
}tree[800005];
using namespace std;
inline int read()
{
	int f=1,x=0;
	char ch=getchar();
	if (ch=='-')
	{
		f=-1;
		ch=getchar();
	}
	while ((ch<'0')||(ch>'9')) ch=getchar();
	while ((ch>='0')&&(ch<='9'))
	{
		x=x*10+ch-48;
		ch=getchar();
	}
	return f*x;
}
inline void build(int root,int l,int r)
{
	tree[root].l=l;
	tree[root].r=r;
	if (l==r)
	{
		tree[root].maxx=a[l];
		return;
	}
	build(root*2,l,(l+r)/2);
	build(root*2+1,(l+r)/2+1,r);
	tree[root].maxx=max(tree[root*2].maxx,tree[root*2+1].maxx);
}
inline void change(int root)
{
	int ll=tree[root].l,rr=tree[root].r;
	if ((ll==x)&&(rr==x))
	{
		tree[root].maxx=y;
		return;
	}
	if (x<=(ll+rr)/2) change(root*2); else
	  change(root*2+1);
	tree[root].maxx=max(tree[root*2].maxx,tree[root*2+1].maxx);
}
inline int find(int root,int l,int r)
{
	int ll=tree[root].l,rr=tree[root].r;
	int mid=(ll+rr)/2;
	if ((ll==l)&&(rr==r)) return tree[root].maxx;
	if (r<=mid) return find(root*2,l,r); else
	  if (l>mid) return find(root*2+1,l,r); else
	    return max(find(root*2,l,(ll+rr)/2),find(root*2+1,(ll+rr)/2+1,r)); 
}
int main()  
{ 
    n=read(),m=read();
	for (int i=1;i<=n;i++) a[i]=read();
	build(1,1,n);
    for (int i=1;i<=m;i++)
    {
    	scanf("%s",&ch);
    	x=read(),y=read();
    	if (ch[0]=='C') change(1); else
    	  printf("%d\n",find(1,min(x,y),max(x,y)));
    }
    return 0;  
}  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章