http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=14799
题意:
Time Limit: 1000MS | Memory Limit: 32768KB | 64bit IO Format: %I64d & %I64u |
Description
Input
Output
用二维线段树,母树上维护的是高度区间对应的子树
特定高度区间对应一个子树,子树上维护的是 每个活跃度区间的最大缘份值
每次操作复杂度 logn*logm n,m分别是子树母树的节点数
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <algorithm> #include <iostream> #include <queue> #include <map> #include <set> #include <vector> using namespace std; const int sub_N=1000*4; const int N=200*4; int max(int a,int b) {return a<b?b:a;} struct sub_node //子线段树节点 { int sl,sr;//sub_l,sub_r int max; //附加信息 }; struct node //母线段树节点 { int l,r; sub_node T[sub_N]; }; node TT[N]; void sub_build(int rt,int sub_rt,int sl,int sr) { TT[rt].T[sub_rt].sl=sl; TT[rt].T[sub_rt].sr=sr; TT[rt].T[sub_rt].max=-1; if (sr==sl) return; int mid=(sl+sr)>>1; sub_build(rt,sub_rt<<1,sl,mid); sub_build(rt,sub_rt<<1|1,mid+1,sr); } void build(int rt,int l,int r,int sl,int sr) { TT[rt].l=l; TT[rt].r=r; sub_build(rt,1,sl,sr); if (l==r) return ; int mid=(l+r)>>1; build(rt<<1,l,mid,sl,sr); build(rt<<1|1,mid+1,r,sl,sr); } void sub_update(int rt,int sub_rt,int active,int love) //在当前【高度区间母树枝】下 更新活跃度为active的子分支 { if (TT[rt].T[sub_rt].sl==TT[rt].T[sub_rt].sr) { TT[rt].T[sub_rt].max=max(TT[rt].T[sub_rt].max,love); return ; } int sl=TT[rt].T[sub_rt].sl; int sr=TT[rt].T[sub_rt].sr; int mid=(sl+sr)>>1; if (active<=mid) sub_update( rt, sub_rt<<1, active, love); else sub_update( rt, sub_rt<<1|1, active, love); TT[rt].T[sub_rt].max=max(TT[rt].T[sub_rt].max,love);//当前rt管辖的活跃度区间包含了active,所以更新max值 } void update(int rt,int hh,int active,int love)//寻找合适的高度区间的母树枝更新 { sub_update(rt,1,active,love); if (TT[rt].l==TT[rt].r) return ; int mid=(TT[rt].l+TT[rt].r)>>1; if (hh<=mid) update(rt<<1,hh,active,love); else update(rt<<1|1,hh,active,love); } int sub_query(int rt,int sub_rt,int sl,int sr) { if (TT[rt].T[sub_rt].sl>=sl &&TT[rt].T[sub_rt].sr<=sr) return TT[rt].T[sub_rt].max; int mid=(TT[rt].T[sub_rt].sl+TT[rt].T[sub_rt].sr)>>1; int ret1=-1,ret2=-1; if (sl<=mid) ret1=sub_query(rt,sub_rt<<1,sl,sr); if (sr>mid) ret2=sub_query(rt,sub_rt<<1|1,sl,sr); return max(ret1,ret2); } int query(int rt,int h1,int h2,int sl,int sr) { if (TT[rt].l>=h1 &&TT[rt].r<=h2) return sub_query(rt,1,sl,sr); int mid=(TT[rt].l+TT[rt].r)>>1; int ret1=-1,ret2=-1; if (h1<=mid) ret1=query(rt<<1,h1,h2,sl,sr); if (h2>mid) ret2=query(rt<<1|1,h1,h2,sl,sr); return max(ret1,ret2); } int main() { double active,love; int hh; int n,i; while(cin>>n) { getchar(); build(1,100,200,0,1000); char op; int h1,h2; double a1,a2; for (i=1;i<=n;i++) { scanf("%c",&op); if (op=='I') { scanf("%d%lf%lf",&hh,&active,&love); int aa=(int)(active*10); int ll=(int)(love*10); update(1,hh,aa,ll); } else { scanf("%d%d%lf%lf",&h1,&h2,&a1,&a2); int aa1=(int)(a1*10); int aa2=(int)(a2*10); if (h1>h2) swap(h1,h2); if (aa1>aa2) swap(aa2,aa1); int ans=query(1,h1,h2,aa1,aa2); if (ans==-1) printf("-1\n"); else printf("%.1lf\n",((double)ans)/10.0); } getchar(); } } return 0; }