中文题不予解释。。。
二维线段树,每个结点都是一棵线段树,那么单点更新时,要把包含所要修改的点的区间信息全部更新,区间查询,只要到对应的区间进行查询就行了
。
自上而下更新
#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #define rep(i,n) for(int i=0;i<(n);++i) #define FOR(i,a,b) for(int i=a;i<=b;++i) #define FORD(i,a,b) for(int i=a;i>=b;--i) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; int n; int Max[101<<2][1001<<2]; int ret; void subbuild(int num,int l,int r,int rt) { Max[num][rt]=-1; if(l==r) return ; int m=(l+r)>>1; subbuild(num,lson); subbuild(num,rson); } void build(int l,int r,int rt) { subbuild(rt,0,1000,1); if(l==r) return ; int m=(l+r)>>1; build(lson); build(rson); } void push_up(int num,int rt) { Max[num][rt]=max(Max[num][rt<<1],Max[num][rt<<1|1]); } void subupdate(int num,int p,int v,int l,int r,int rt) { Max[num][rt]=max(Max[num][rt],v); if(l==r) return ; int m=(l+r)>>1; if(p<=m) subupdate(num,p,v,lson); else subupdate(num,p,v,rson); push_up(num,rt); } void update(int p1,int p2,int v,int l,int r,int rt) { subupdate(rt,p2,v,0,1000,1); if(l==r) return ; int m=(l+r)>>1; if(p1<=m) update(p1,p2,v,lson); else update(p1,p2,v,rson); } void subquery(int num,int L,int R,int l,int r,int rt) { if(L<=l&&r<=R){ ret=max(ret,Max[num][rt]); return ; } int m=(l+r)>>1; if(L<=m) subquery(num,L,R,lson); if(m<R) subquery(num,L,R,rson); } void query(int L1,int R1,int L2,int R2,int l,int r,int rt) { if(L1<=l&&r<=R1){ subquery(rt,L2,R2,0,1000,1); return ; } int m=(l+r)>>1; if(L1<=m) query(L1,R1,L2,R2,lson); if(m<R1) query(L1,R1,L2,R2,rson); } int main() { while(scanf("%d",&n),n){ build(100,200,1); char op[20]; while(n--){ scanf("%s",op); if(op[0]=='I'){ int p1; double p2,v; scanf("%d%lf%lf",&p1,&p2,&v); update(p1,int(10*p2),int(10*v),100,200,1); }else{ int l1,r1;double l2,r2; scanf("%d%d%lf%lf",&l1,&r1,&l2,&r2); if(l1>r1) swap(l1,r1); if(l2>r2) swap(l2,r2); ret=-1; query(l1,r1,int(10*l2),int(10*r2),100,200,1); if(ret==-1) printf("-1\n"); else printf("%.1lf\n",ret/10.0); } } } return 0; }