http://acm.hdu.edu.cn/showproblem.php?pid=1754
求区间最大数,并且有单点操作
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
#define MAX 200010
typedef struct
{
int l;
int r;
int max;
} Tree;
Tree tree[MAX*4];
int build(int i,int l,int r) //建树
{
int mid;
tree[i].l=l;
tree[i].r=r;
tree[i].max=0;
if(l==r)
{
return 0;
}
mid=(l+r)/2;
build(i*2,l,mid);
build(i*2+1,mid+1,r);
}
int insert(int i,int k,int v) //插入
{
tree[i].max=v >tree[i].max?v:tree[i].max;
if(tree[i].l==tree[i].r)
return 0;
else
{
int mid=(tree[i].l+tree[i].r)/2;
if(mid<k)
insert(i*2+1,k,v);
else
insert(i*2,k,v);
}
}
int del(int i,int k,int v) //先删除
{
if(tree[i].l==tree[i].r)
{
tree[i].max=v;
return i;
}
else
{
int mid=(tree[i].l+tree[i].r)/2;
if(mid<k)
del(i*2+1,k,v);
else
del(i*2,k,v);
}
}
void change(int i) //再倒着更新
{
if(i==1)
return ;
if(i%2==1)
{
tree[(i-1)/2].max=max(tree[i-1].max,tree[i].max);
change((i-1)/2);
}
else
{
tree[i/2].max=max(tree[i].max,tree[i+1].max);
change(i/2);
}
}
int findmax(int i,int x,int y) //找区间的最大
{
int ans=0,mid;
if((x<=tree[i].l)&&(y>=tree[i].r))
return tree[i].max;
ans=0;
mid=(tree[i].l+tree[i].r)/2;
if (x<=mid) ans= max(ans,findmax(i*2,x,y));
if (y>mid) ans= max(ans,findmax(i*2+1,x,y));
return ans;
}
int N,M;
int main()
{
while(~scanf("%d%d",&N,&M))
{
build(1,1,N);
int a;
char Q[3];
for(int i=1; i<=N; i++)
{
scanf("%d",&a);
insert(1,i,a);
}
for(int i=1; i<=M; i++)
{
scanf("%s",Q);
if(Q[0]=='Q')
{
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",findmax(1,x,y));
}
else
{
int i,v;
scanf("%d%d",&i,&v);
int t=del(1,i,v);
change(t);
}
}
}
}