题目链接:acm.hdu.edu.cn/showproblem.php?pid=1823
Problem Description
世界上上最远的距离不是相隔天涯海角
而是我在你面前
可你却不知道我爱你
―― 张小娴
前段日子,枫冰叶子给Wiskey做了个征婚启事,聘礼达到500万哦,天哪,可是天文数字了啊,不知多少MM蜂拥而至,顿时万人空巷,连扫地的大妈都来凑热闹来了。―_―|||
由于人数太多,Wiskey实在忙不过来,就把统计的事情全交给了枫冰叶子,自己跑回家休息去了。这可够枫冰叶子忙的了,他要处理的有两类事情,一是得接受MM的报名,二是要帮Wiskey查找符合要求的MM中缘分最高值。
Input
本题有多个测试数据,第一个数字M,表示接下来有连续的M个操作,当M=0时处理中止。
接下来是一个操作符C。
当操作符为‘I’时,表示有一个MM报名,后面接着一个整数,H表示身高,两个浮点数,A表示活泼度,L表示缘分值。 (100<=H<=200, 0.0<=A,L<=100.0)
当操作符为‘Q’时,后面接着四个浮点数,H1,H2表示身高区间,A1,A2表示活泼度区间,输出符合身高和活泼度要求的MM中的缘分最高值。 (100<=H1,H2<=200, 0.0<=A1,A2<=100.0)
所有输入的浮点数,均只有一位小数。
Output
对于每一次询问操作,在一行里面输出缘分最高值,保留一位小数。
对查找不到的询问,输出-1。
Sample Input
8
I 160 50.5 60.0
I 165 30.0 80.5
I 166 10.0 50.0
I 170 80.5 77.5
Q 150 166 10.0 60.0
Q 166 177 10.0 50.0
I 166 40.0 99.9
Q 166 177 10.0 50.0
50.0
99.9
二维线段树模板题:所谓的二维线段树,只不过是在一维线段树的每个节点再建一棵子树,以保存该节点的区间的第二维信息;一维线段树维护身高信息,二维维护活泼度;每次修改和查询先对一维访问,再对二维访问;然后就没了。。。。
AC code:
#include<iostream>
#include<cstdio>
#include<vector>
#include<stack>
#include<set>
#include<queue>
#include<map>
#include<string>
#include<cstring>
#include<iomanip>
#include<ctime>
#include<fstream>
#include<cstdlib>
#include<algorithm>
using namespace std;
#define eps 0x3f3f3f3f;
#define pii pair<int, int>
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define per(i,a,b) for(int i=a;i<=b;i++)
#define rep(i,a,b) for(int i=a;i>=b;i--)
#define input(a) scanf("%d",&a)
#define input1(a,b) scanf("%d%d",&a,&b)
#define output(a) printf("%d\n",a)
#define lson le,mid,2*k
#define rson mid+1,ri,2*k+1
#define getmid int mid=(le+ri) >> 1;
#define PI 3.1415926535897932384626433832795
const int maxn=1000+10;
char c;
double ac,love,a1,a2,ans=-1;
int act,h1,h2,act1,act2,h,m;
struct sontree{
int ll,rr;
double maxv;
};
struct node{
int l,r;
sontree sub_tree[maxn<<2]; //子树
}tree[110<<2];
void build_son(int k1,int lee,int rii,int kk) //建立二维
{
tree[k1].sub_tree[kk].ll=lee;
tree[k1].sub_tree[kk].rr=rii;
tree[k1].sub_tree[kk].maxv=-1.0;
if(lee==rii) return;
int mid=(tree[k1].sub_tree[kk].ll+tree[k1].sub_tree[kk].rr)>>1;
build_son(k1,lee,mid,kk<<1);
build_son(k1,mid+1,rii,kk<<1|1);
}
void build(int le,int ri,int k) //建立一维
{
build_son(k,0,1000,1);
tree[k].l=le;tree[k].r=ri;
if(le==ri) return;
getmid;
build(le,mid,k<<1);
build(mid+1,ri,k<<1|1);
}
void query_son(int k1,int kk) //查询二维
{
int le=tree[k1].sub_tree[kk].ll;
int ri=tree[k1].sub_tree[kk].rr;
if(le>=act1&&ri<=act2){
ans=max(ans,tree[k1].sub_tree[kk].maxv);
return;
}
getmid;
if(act1<=mid) query_son(k1,kk<<1);
if(act2>mid) query_son(k1,kk<<1|1);
}
void query(int k) //查询一维
{
if(tree[k].l>=h1&&tree[k].r<=h2){
query_son(k,1);
return;
}
int mid=(tree[k].l+tree[k].r)>>1;
if(h1<=mid) query(k<<1);
if(h2>mid) query(k<<1|1);
}
void update_son(int k1,int kk) //更新二维
{
int le=tree[k1].sub_tree[kk].ll;
int ri=tree[k1].sub_tree[kk].rr;
if(le==ri){
tree[k1].sub_tree[kk].maxv=max(tree[k1].sub_tree[kk].maxv,love);
return;
}
getmid;
if(act<=mid) update_son(k1,kk<<1);
else update_son(k1,kk<<1|1);
tree[k1].sub_tree[kk].maxv=max(tree[k1].sub_tree[kk<<1].maxv,tree[k1].sub_tree[kk<<1|1].maxv);
}
void update(int k) //更新一维
{
update_son(k,1);
if(tree[k].l==tree[k].r) return;
int mid=(tree[k].l+tree[k].r)>>1;
if(h<=mid) update(k<<1);
else update(k<<1|1);
}
int main()
{
while(input(m),m){
build(100,200,1);
while(m--){
scanf("\n%c",&c);
if(c=='I'){
scanf("%d%lf%lf",&h,&ac,&love);
act=(int)(10.0*ac);
update(1);
}
else{
scanf("%d%d%lf%lf",&h1,&h2,&a1,&a2);
act1=(int)(10.0*a1);
act2=(int)(10.0*a2);
if(h1>h2) swap(h1,h2); //注意保证h1<h2,act1<act2
if(act1>act2) swap(act1,act2);
ans=-1;
query(1);
if(ans==-1.0) printf("%d\n",-1);
else printf("%.1lf\n",ans);
}
}
}
}