做了hdu 1166 后,这道题目只要稍稍修改一下就可以了。
不过在一直卡在一个小bug 里面, 花了好长的时间
time 840ms
#include <iostream>
#include <stdio.h>
using namespace std;
const int N=20005;
int Max[N<<2];
int max(int a,int b)
{return a>b?a:b ;}
void push_up(int rt)
{
Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);
}
void build(int l,int r,int rt)
{
if(l==r)
{ scanf("%d",&Max[rt]);
return ;
}
int m=(l+r)>>1;
build(l,m,rt<<1);
build(m+1,r,rt<<1|1);
push_up(rt);
}
void updata(int l,int r,int rt,int pos,int v)
{
if(l==r)
{
Max[rt]=v;
return ;
}
int m=(l+r)>>1;
if(pos<=m)
updata(l,m,rt<<1,pos,v);
else
updata(m+1,r,rt<<1|1,pos,v);
push_up(rt);
}
int query(int l,int r,int rt,int L,int R)
{
if(L<=l&&R>=r)
{
return Max[rt];
}
int m=(l+r)>>1;
int ret=0;
if(L<=m)
ret=max(ret,query(l,m,rt<<1,L,R));
if(R>m)
ret=max(ret,query(m+1,r,rt<<1|1,L,R));
return ret;
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
build(1,n,1);
while(m--)
{
int a,b;
char op[2];
scanf("%s%d%d",op,&a,&b);
if(op[0]=='Q')
printf("%d\n",query(1,n,1,a,b));
else
updata(1,n,1,a,b);
}
}
}
zkw 线段树做法
time 561ms
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <memory.h>
using namespace std;
const int N=200005;
int T[N<<2],M;
void push_up(int rt)
{
T[rt]=max(T[rt<<1],T[rt<<1|1]);
}
void build(int n)
{
for(M=1;M<=n+1;M<<=1);
for(int i=M+1;i<=M+n;i++)
scanf("%d",&T[i]);
for(int i=M-1;i>0;i--)
push_up(i);
}
void updata(int n,int v)
{
for(T[n+=M]=v,n>>=1;n;n>>=1)
push_up(n);
}
int query(int s,int t)
{
int ans=-1;
for(s=s+M-1,t=t+M+1;s^t^1;s>>=1,t>>=1)
{
if(~s&1) ans=max(ans,T[s^1]);
if( t&1) ans=max(ans,T[t^1]);
}
return ans;
}
int main()
{
char op[2];
int n,m,a,b;
while(~scanf("%d%d",&n,&m))
{
memset(T,0,sizeof(T));
build(n);
while(m--)
{
scanf("%s%d%d",op,&a,&b);
if(op[0]=='U')
updata(a,b);
else
printf("%d\n",query(a,b));
}
}
}