HDU1823--Luck and Love--二维线段树

题目链接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

0
Sample Output
80.5

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);
			}
		}
	}
} 

 
 

 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值