#include <iostream> #include <stdio.h> using namespace std; int tmp; int max(int a,int b) { return a>b?a:b; } struct code { int l,r,max; }xd[600001];//一般开最大值的三倍大小 int creat(int u,int l,int r) //创建树 { int mid=(l+r)/2; xd[u].l=l;xd[u].r=r;xd[u].max=0; if(l!=r) { creat(u+u,l,mid); creat(u+u+1,mid+1,r); } } void work(int u,int l,int r) //寻找区间最大值 { //if(tmp>xd[u].max) return; //优化,更省时 int mid=(xd[u].l+xd[u].r)/2; if(xd[u].l==l&&xd[u].r==r) tmp=max(tmp,xd[u].max); else if(l>mid) return work(u+u+1,l,r); else if(r<=mid) return work(u+u,l,r); else {work(u+u,l,mid);work(u+u+1,mid+1,r);} } void updata(int u,int old,int xin) //更新节点最大值 { int mid=(xd[u].l+xd[u].r)/2; if(xd[u].l==xd[u].r) {xd[u].max=xin;return;} else { if(old<=mid) updata(u+u,old,xin); else updata(u+u+1,old,xin); xd[u].max=max(xd[u+u].max,xd[u+u+1].max); //利用递归实现将所有与updata叶子有关的节点进行更新 } } int main() { int n,m,num,a,b; char c[5]; while(scanf("%d%d",&n,&m)!=EOF) { creat(1,1,n); for(int i=1;i<=n;i++) { scanf("%d",&num); updata(1,i,num); } while(m--) { scanf("%s%d%d",c,&a,&b); if(c[0]=='Q') { tmp=-1; work(1,a,b); printf("%d\n",tmp); } else { updata(1,a,b); } } } }
下面是再度优化的方法,用于timelimited、
#include <iostream> #include <stdio.h> using namespace std; int tmp,num[200001];//存储输入 int max(int a,int b) { return a>b?a:b; } struct code { int l,r,max; }xd[600001]; void creat(int u,int l ,int r) { xd[u].l=l;xd[u].r=r; int mid=(l+r)/2; if(l==r) xd[u].max=num[l]; else { creat(u+u,l,mid); creat(u+u+1,mid+1,r); xd[u].max=max(xd[u+u].max,xd[u+u+1].max);//利用递归,在创建同时维护最大值,须先输入数据后创建 } } void updata(int u,int old,int xin) { int mid=(xd[u].l+xd[u].r)/2; if(xd[u].l==xd[u].r) xd[u].max=xin; else { if(old<=mid) updata(u+u,old,xin); else updata(u+u+1,old,xin); xd[u].max=max(xd[u+u].max,xd[u+u+1].max); } } void work(int u,int l,int r) { int mid=(xd[u].l+xd[u].r)/2; if(xd[u].l==l&&xd[u].r==r) tmp=max(tmp,xd[u].max); else { if(l>mid) work(u+u+1,l,r); else if(r<=mid) work(u+u,l,r); else { work(u+u,l,mid); work(u+u+1,mid+1,r); } } } int main() { int n,m,a,b; char c[5]; while(scanf("%d%d",&n,&m)!=EOF) { for(int i=1;i<=n;i++) { scanf("%d",&num[i]); } creat(1,1,n); while(m--) { scanf("%s%d%d",c,&a,&b); if(c[0]=='Q') { tmp=-1; work(1,a,b); printf("%d\n",tmp); } else { updata(1,a,b); } } } }