HDU1823-二维线段树

在Visual Studio中搭建Dynamo Python开发环境,效率飞一般的增长 阅读详情

本题是二维线段树模板,题目链接:HDU1823-Luck and Love

我给出题目:

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代码吧,下面有详细注释:


#include <iostream>
#include <cstdio>
#include <stdio.h>
#include <cmath>
#define maxn 222
using namespace std;
//第二维度,注意m要放在第二维,因为一定要搜完第一维和第二维才能确定m的值
struct node{
	int al;//活泼度
	int ar;
	double m;//存结果
};
struct node1{
	int hl;身高
	int hr;
	node stu[4444];//在第一维里面建立到第二维的通道,用于连接第一维和第二维
}ans[maxn<<2];
void sub_build(int id,int rt,int al,int ar)//第二维线段树,记录活泼度
{
	ans[id].stu[rt].al=al;//通过第一维里面的通道stu来访问第二维线段树
	ans[id].stu[rt].ar=ar;
	ans[id].stu[rt].m=-1.0;//答案都初始化为-1.0
	if(al==ar)return;
	int m=(al+ar)>>1;
	sub_build(id,rt<<1,al,m);//在第一维线段树的基础上建立二维线段树,id是第一维的坐标,不能改变,rt是第二维线段树的坐标
	sub_build(id,rt<<1|1,m+1,ar);
	
}
//建立第一维线段树,记录的是身高h的情况
void build(int id,int hl,int hr,int al,int ar)
{
	ans[id].hl=hl;
	ans[id].hr=hr;
	sub_build(id,1,al,ar);//同时建立第二维线段树
	if(hl==hr)return;
	int m=(hl+hr)>>1;
	build(id<<1,hl,m,al,ar);//建立左子树
	build(id<<1|1,m+1,hr,al,ar);//建立右子树
}
void sub_add(int id,int rt,int a,double l)
{
	ans[id].stu[rt].m=max(ans[id].stu[rt].m,l);//储存答案
	if(ans[id].stu[rt].al==ans[id].stu[rt].ar)return;
	int m=(ans[id].stu[rt].al+ans[id].stu[rt].ar)>>1;
	if(a<=m)sub_add(id,rt<<1,a,l);
	else sub_add(id,rt<<1|1,a,l);
	ans[id].stu[rt].m=max(ans[id].stu[rt<<1].m,ans[id].stu[rt<<1|1].m);//将答案向上更新,否则全部都会等于初始化的-1.0,导致答案错误
}
void add(int id,int h,int a,double l)
{
	sub_add(id,1,a,l);//将a的值传入第二维线段树
	if(ans[id].hl==ans[id].hr)return;
	int m=(ans[id].hl+ans[id].hr)>>1;
	if(h<=m)add(id<<1,h,a,l);//判断插入左子树或右子树
	else add(id<<1|1,h,a,l);
}
double sub_query(int id,int rt,int al,int ar)
{
	if(ans[id].stu[rt].al==al&&ans[id].stu[rt].ar==ar)return ans[id].stu[rt].m;//若活泼度也符合范围,直接返回答案m
	int m=(ans[id].stu[rt].al+ans[id].stu[rt].ar)>>1;
	if(ar<=m)return sub_query(id,rt<<1,al,ar);//若要查找的范围的最大值ar比中间值m小,直接从左子树查找
	else if(al>m)return sub_query(id,rt<<1|1,al,ar);//<span style="font-family: Arial, Helvetica, sans-serif;">若要查找的范围的最小值al比中间值m大,直接从右子树查找</span>
	else return max(sub_query(id,rt<<1,al,m),sub_query(id,rt<<1|1,m+1,ar));//不然就两边同时查找,返回较大的那个
}
double query(int id,int hl,int hr,int al,int ar)
{
	if(ans[id].hl==hl&&ans[id].hr==hr)//若身高符合范围,则进入第二维线段树,查找活泼度
		return sub_query(id,1,al,ar);
	int m=(ans[id].hl+ans[id].hr)>>1;
	if(hr<=m)return query(id<<1,hl,hr,al,ar);//要查找的身高最大值hr都比当前查找范围的中间值m小,则从左子树中查找
	else if(hl>m)return query(id<<1|1,hl,hr,al,ar);//同上,要查找的最小值hl都比当前范围的中间值m大,从右子树中查找
	else return max(query(id<<1|1,m+1,hr,al,ar),query(id<<1,hl,m,al,ar));//否则同时查找,返回较大的那个
}
int main()
{
	int m;
	while(scanf("%d",&m)&&m)
	{
		build(1,100,200,0,1000);//1是线段树的根,100-200是身高范围,0-1000是活泼度,活泼度本来是0-100的浮点数,将其转化成0-1000的整形方便建树计算
		char cmd[4];
		while(m--)
		{
			scanf("%s",cmd);
			if(cmd[0]=='I')
			{
				int h;
				double a,l;
				scanf("%d%lf%lf",&h,&a,&l);
				int aa=a*10;//将活泼度转化成整数
				add(1,h,aa,l);//插入一个新的节点
			}else{
				int hl,hr;
				double al,ar;
				scanf("%d%d%lf%lf",&hl,&hr,&al,&ar);
				int aa=10*al,bb=ar*10;//同上
				if(hl>hr)//防止访问越界
				{
					int temp=hl;
					hl=hr;
					hr=temp;
				}
				if(aa>bb)//同上
				{
					int temp=aa;
					aa=bb;
					bb=temp;
				}
				double res=query(1,hl,hr,aa,bb);//查询结果
				if(res==-1.0)printf("-1\n");
				else printf("%.1lf\n",res);
			}
		}
	}
	return 0;
}


PS:依我个人之见,可以将二维线段树看成是一个矩形,建树和查找的过程都可以看成是先确定行或列,然后再在列或行里进行进一步的操作。用这种思考方式,建树和查找的思路都会非常清晰。

还有就是我上面的代码用了重名,例如都用hl和hr表示身高的左右范围,纯属个人习惯。你们看的时候要注意区分线段树里的hl,hr,al,ar和你传进去的hl,hr,al,ar。传进去的值是不能改变的,用于确定查询范围。要改变的是你查找的节点,也就是线段树里的值。为了不搞混你可以取不同的名字~~

UE 顶点动画工具 (VAT) 导入模型需要勾选全精度UV。 阅读详情

相关推荐

ndnSIM学习笔记(一)

在接下来的一段时间要用ndnSIM来做自己的仿真网络,需要系统的学习相关内容,以下为内容记录。1.安装      1.1核心依赖(必需的)             • python &gt;= 2.6             • libsqlite3             • libcrypto++             • pkg-config             • Boost lib...

gaonjzzz的博客 2985

HDU1823 二维线段树 求最大值

Luck and Love Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5382    Accepted Submission(s): 1344 Problem Description 世界上上最远的距离不是

Ignorance 1060

【Solidworks学习使用(1)__2022版本保姆级安装方法】

Solidworks 2020安装

coder-kimbell的博客 6247

HDU1823(二维线段树)

题目:Luck and Love   题意:当操作符为‘I’时,表示有一个MM报名,后面接着一个整数,H表示身高,两个浮点数,A表示活泼度,L表示缘分值。 (100 当操作符为‘Q’时,后面接着四个浮点数,H1,H2表示身高区间,A1,A2表示活泼度区间,输出符合身高和活泼度要求的MM中的 缘分最高值。 (100 其实对于二维线段树,可以这样理解: 母树保存x轴上面的信息;子树保存当

ACdreamer 1784

从零开始理解二极管限幅:5种典型电路设计及实际应用场景解析

本文系统解析了二极管限幅电路的五大经典拓扑,包括串联与并联型上下限幅及双向限幅。通过剖析其核心原理与二极管的单向导电性、正向压降特性,结合ADC输入保护、电源管理、音频处理等实际应用场景,提供了从器件选型到设计陷阱规避的完整实战指南,帮助工程师为信号构建可靠的“安全笼”。

2y3u4i5o6p的博客 1034

开源网格划分软件-Gmsh二次开发教程 (4)网格生成与控制​

​本章将深入讲解Gmsh的网格生成技术,包括全局/局部网格控制、边界层生成、自适应细化等,并提供完整的代码示例。

ZQGG的博客 1472

hdu 1823 线段树(非二维做法)

都说这题是二维线段树裸题,不过我二维线段树有点麻烦 也不太想写(还是得学的) 我就直接开200棵线段树了 这种方法在某一维很小的时候 是完全适用的 复杂度最多 100*1000*log(1000) 完全不虚 #include<cstdio> #include<cstring> #include<algorithm> using namespace s...

weixin_43824564的博客 888

【网络】Ikuai中如何添加/更换虚拟机(图文)

Ikuai 添加虚拟机教程

qq_20623849的博客 6533

hdu1823二维线段树,单点跟新,区间求最大值。

/* 思路:以身高为x,活泼度为y建立二维线段树,然后其余就是二维线段树的区间最值和单点跟新. 然后有 升高和活泼度相同,但是缘分不同的数据。 还有输入查询数据的时候 有可能 区间大的输入在区间小的的前面 */ #include #include #include #include using namespace std; int m; int sum[102*4+10][1002*4+10];

旺旺的博客 557

Android SystemUI——车载CarSystemUI加载(八)

车载 CarSystemUI 是指专门为汽车环境设计的用户界面和用户体验(UI/UX),它通常与 Android Automotive OS 或其他嵌入式操作系统一起工作,为驾驶者和乘客提供安全、直观且高效的交互方式。Android Automotive OS 是 Google 专门为汽车开发的操作系统版本,它基于 Android 平台,并针对车辆内部的使用进行了优化。

小旭的专栏 2172

Unity-TextMeshPro如何扩展材质实现字体Face+Outline流光效果

前言 TexeMeshPro 是Unity的一个Text文本插件,实现了比UGUI的Text,更好看的效果,跟高效的性能,所以深受大家的喜欢,但是再好的插件,也不是万能的,比如我们的策划有个新需求,要我们的VIP的名字比普通玩家有更好看的效果,例如:字体流光,外发光颜色扰动,字体贴图等等。那我们就需要去扩展TextMeshPRo的shader功能了。如下图所示 本文,我就带大家一起来扩展一下:如何扩展TextMeshProUGUI TextMesh原始面板 扩展功能后的面板 扩展TextMeshPro

TxNet 9673

(二维线段树)hdu 1823 Luck and Love & poj 1195 Mobile phones & poj 2155 Matrix

题目: hdu poj 题意: 二维线段树的查找与添加 注意: 二维线段树的更新方式要全更新: (更新范围) ..... ..... ..... ..... 有一种错误的更新方式: (更新范围) . . . ..... 错误的代码 void addx(int x, int y, int v, int l, int r, int pos){ if (l == r){ addy(pos, y, v, 1, Size, 1); return; } int mi

ymxyld的博客 307

快速入门必看!RT-DETR手把手训练自己的数据集去跑实验,基于 ultralytics 仓库源码改进,配置虚拟环境,准备数据集、训练、验证、推理测试 ,实现0到1的完整教学过程。

本文介绍了使用Ultralytics框架训练RT-DETR模型的全流程。首先需要创建Python 3.10虚拟环境,安装指定版本的PyTorch和相关依赖包。然后准备数据集,修改配置文件,并详细介绍训练、验证和推理三个核心步骤的代码实现。训练阶段使用RTDETR类加载模型配置,设置训练参数;验证阶段评估模型性能;推理阶段可对图片、视频等进行预测。文中还提供了清华大学镜像源加速下载,以及详细的参数配置说明,帮助用户快速搭建RT-DETR目标检测模型。

Ai缝合怪、助力小伙伴高效发论文 5540

hdu 1823(二维线段树入门题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1823 Luck and Love Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5457    Accepted Submis

T_T 1041

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

二维线段树(hdu1823)

二维线段树其实也没有其他新知识,从名字上也能看出,他不过就是将一维变成二维,把之前的一维线段树每个节点再扩展成一棵线段树如下图: 图上红标号点是一维树,蓝标号点就是二维树。 从图也可看出,我们之所以要用二维线段树是因为你要得到的答案限制条件用一维无法控制,而二维线段树可以在满足一维线段树条件的情况下在二维还可以有给我们限制条件的空间,最终就可以从一维到二维再到答案。 图看起来比一维线段树...

weixin_30480651的博客 344

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

hdu1823(二维线段树模板题)

hdu1823 题意 单点更新,求二维区间最值。 分析 二维线段树模板题。 二维线段树实际上就是树套树,即每个结点都要再建一颗线段树,维护对应的信息。 一般一维线段树是切割某一可变区间直到满足所要查询区间,求最值、求和等,二维就是先切割第一维的区间,再去切割第二维的区间。 code #include<bits/stdc++.h> using namespace std; #define...

weixin_34341229的博客 225

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

【二维线段树】HDU 1823

很裸的一道二维线段树,第一次做,其实二维的线段树也就是树套树,先一维再第二维,第一、二维的操作都很类似。 说回hdu这道题,有点水,提交的时候记得交c++,g++会wa死你! #define N 210 struct node{ int al,ar; double mx; }; struct node1{ int hl,hr; node subt[4000];

leolin_的专栏 2488

HDU1823-Luck and Love-二维线段树(模板)

HDU1823-Luck and Love-二维线段树(模板) 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1823 好吧,给这题跪了。。。orz.... 一道非常基础的二维线段树的模板题; 可是细节非常多;尤其注意了; swap函数会丢失精度,用double就等着WA到死吧。。...

weixin_30832351的博客 79

HDU 1823 二维线段树

第一次写二维线段树,参考了别人代码,主要思路是类似于一维线段树,只不过线段二分思想变成了矩阵四分。#include #include int seg[8000*800],n; int max(int a,int b) { return a>b?a:b; } void ud(int al,int ar,int hl,int hr,int a,int h,int d,int i) {

终究我要华丽逆袭 691

HDU1823二维线段树+易错点

话说一开始做线段树看到这题想到应该就是所谓的二维线段树,于是就敲了一下,敲完3K多B之后提交TLE之后一直不知道怎么回事于是去找了相关代码来参考,发现查找,更新,建树的思想是一样,但是我SB了,竟然把左右子树的位置还记下来了,因为之前一直用的动态储存就是指针,所以数据结构中必须要有两个子树的指针,但是这次用了静态的数组来储存,所以习惯性的就把左右儿子的信息记录下来了,后来才发现根本不用的因为如果父节点是N,那左儿子的下标必然是2*N,右儿子下标也必然是2*N+1,因此把这两个变量去掉了,并且操作一律用位运算

andychanry的专栏 1013

hdu1823 二维线段树

第一次写二维线段树,参考了别人代码,主要思路是类似于一维线段树,只不过线段二分思想变成了矩阵四分。#include #include int seg[8000*800],n; int max(int a,int b) { return a>b?a:b; } void ud(int al,int ar,int hl,int hr,int a,int h,int d,int i) {

终究我要华丽逆袭 936

【hdu1823】【二维线段树】Luck and Love

这道题是一道二维线段树的裸题。 由于浮点数最多一位,所以我们可以先转化成整数,输出时除以10;另外当两个人身高和活泼度都相等时,要取魅力值大的一个,所以要取最大而不能直接赋值。 代码: #include #include #include using namespace std; const int maxn1 = 100 + 10; const int maxn2 = 1000 + 1

I'm dreamer 628

hdu 1823 - 二维线段树

题目链接:点击这里   解题思路: 把身高看做一维,活泼度看做一维,做基本的二维线段树区间求最大,小数点先乘10把它化为整数才能做线段树。   #include&lt;cstdio&gt; #include&lt;iostream&gt; #include&lt;cstring&gt; #define lson l,mid,rt&lt;&lt;1 #define rson mid+1,...

过路人丶的博客 314

hdu 1823 二维线段树点更新

题意: 中文题 解题思路: 利用二维线段树的点更新即可 注意: 二维线段树的在点更新时,需先更新局部的子区间,然后更新全局区间

watermelon1993的专栏 512

hdu1823 Luck and Love 二维线段树

首先发表下做完后的感受:这题真他妈操蛋!!!一个简单的二维线段树,搞了一下午啊啊。。 思路:首先根据身高建一棵线段树,然后在每个节点上再以活泼度建一棵线段树,并记录每个区间的最大缘分值。 重点说细节了:在查询时可能会有A1>A2,H1>H2;然后就是插入数据时可能会有缘分值为0的数据,所以初始化时不要初始化为0;可能会插入身高和活泼度相同但缘分值不同的数据,因此还需要比较一下;最后一点,我写(

程序猿之路 1303
上一篇: 伸展树的构建和最基本的插入与查询
下一篇: 用C / C++ 实现快速排序
P_rogrammer
博客等级 码龄12年 0粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值