当前位置: 首页 > news >正文

阴影映射(线段树)

实时阴影是电子游戏中最为重要的画面效果之一。在计算机图形学中,通常使用阴影映射方法来实现实时阴影。

游戏开发部正在开发一款 2D 游戏,同时希望能够在 2D 游戏中模仿 3D 游戏的光影效果,请帮帮游戏开发部!

给定 x-y 平面上的 n 个矩形,矩形的边界平行于坐标轴,且可能相互重叠。同时给定点光源的坐标。现有 m 次操作,每次操作添加或删除一个矩形,或询问 x 轴上的一点是否在阴影内。

输入格式

第一行,两个整数 n , m n,m n,m( 1 ≤ n , m ≤ 2 × 1 0 5 1≤n,m≤2×10^5 1n,m2×105)。
第二行,两个整数 l x , l y l_x,l_y lx,ly,表示光源的坐标为 ( l x , l y ) (l_x,l_y) (lx,ly) ∣ l x ∣ ≤ 2 × 1 0 5 , 0 < l y ≤ 2 × 1 0 5 |l_x|≤2×10^5,0<l_y≤2×10^5 lx2×105,0<ly2×105
接下来 n n n 行,每行 5 个整数 i d , x , y , w , h id,x,y,w,ℎ id,x,y,w,h,表示编号为 i d id id 的矩形,左下角坐标为 ( x , y ) (x,y) (x,y),宽为 w w w,高为 h ℎ h
接下来 m m m 行,每行先输入一个正整数 o p t opt opt∈[1,3]。

  • o p t = 1 opt=1 opt=1,则接下来输入 5 个整数 i d , x , y , w , h id,x,y,w,ℎ id,x,y,w,h,表示增加一个编号为 i d id id,且左下角坐标为 ( x , y ) (x,y) (x,y),宽和高为 w w w h ℎ h 的矩形。
  • o p t = 2 opt=2 opt=2,则接下来输入一个整数 i d id id,表示删除编号为 i d id id 的矩形。
  • o p t = 3 opt=3 opt=3,则接下来输入一个整数 p p p,表示查询坐标 ( p , 0 ) (p,0) (p,0) 是否在阴影中。

1 ≤ i d ≤ 4 × 1 0 5 1≤id≤4×10^5 1id4×105
∣ x ∣ ≤ 2 × 1 0 5 , 0 < y ≤ 2 × 1 0 5 |x|≤2×10^5,0<y≤2×10^5 x2×105,0<y2×105
0 < w , h ≤ 2 × 1 0 5 0<w,ℎ≤2×10^5 0<w,h2×105
∣ p ∣ ≤ 1 0 9 |p|≤10^9 p109
保证任意时刻场景中所有矩形的 i d id id 互不相同。保证所有矩形各个顶点的 y y y 坐标一定严格小于光源的 y y y坐标。若询问点在阴影的边界上,仍算作在阴影内。

输出格式

对于每个 o p t = 3 opt=3 opt=3 的询问,若询问的点在阴影中,则输出一行 YES,否则输出一行 NO

样例

input
3 19
4 7
1 1 1 2 1
2 6 1 2 3
3 5 2 4 1
3 -1
3 0
3 2
3 3
3 4
3 5
3 6
3 12
3 13
3 14
1 4 4 5 2 1
3 3
3 4
3 5
3 18
3 19
2 1
3 2
3 3
output
NO
YES
YES
NO
NO
NO
YES
YES
YES
NO
NO
YES
YES
YES
NO
NO
NO

提示

在进行所有修改操作之前,所有矩形的位置如下 (绿色部分为阴影区域):
002.png
在加入一个矩形后,所有矩形的位置如下:
003.png
在删除一个矩形后,所有矩形的位置如下:
004.png

很容易想到利用线段树维护阴影区间,添加阴影即为在[l,r]范围内进行+1操作,删除阴影为-1

但是本题的数据范围过大,特别注意当光源与矩形非常接近时,光线几乎平行于x轴,这时用long long都会存在爆精度问题

所以必须进行离散化

我们可以发现需要用到的坐标是有限的,最多不超过 2 × n + m 2×n+m 2×n+m个坐标点,用到的坐标点为线段端点(l,r)和查询位置p

AC代码如下

注意这题的时间复杂度卡的很死,需要采用IO加速,同时切忌使用STL容器

#include <iostream>
#include <algorithm>
#include <map>
#include <cmath>
using namespace std;
#define int long long
const int max_n = 5e5 + 50;
const int max_m = 5e5 + 50;
const int max_len = 1e6 + 50;
const double eps = 1e-8;typedef struct {int idx, x1, y1, x2, y2;
}node;typedef struct {int opt[6];
}query;typedef struct {double first, second;
}line;int n, m;
node arr[max_n];
query qarr[max_m];
int tmpidx, lineidx;
double tmparr[max_len];
line lines[max_n + max_m];
map<double, int>dict;
int tree[max_len];inline int read() {int x = 0, y = 1; char c = getchar();while (c < '0' || c > '9') {if (c == '-') y = -1;c = getchar();}while (c >= '0' && c <= '9') {x = x * 10 + c - '0';c = getchar();}return x * y;
}inline int lowbit(int x) {return x & -x;
}int ask(int p) {int res = 0;for (int i = p; i > 0; i -= lowbit(i)) {res += tree[i];}return res;
}void add(int p, int x) {for (int i = p; i < max_len; i += lowbit(i)) {tree[i] += x;}
}double project(int x, int y) {if (x == arr[0].x1) return x;double k = double(y - arr[0].y1) / double(x - arr[0].x1);double b = k * x - y;return b / k;
}void process(node n) {double l, r, ret;l = r = project(n.x1, n.y1);ret = project(n.x1, n.y2);l = min(l, ret); r = max(r, ret);ret = project(n.x2, n.y1);l = min(l, ret); r = max(r, ret);ret = project(n.x2, n.y2);l = min(l, ret); r = max(r, ret);tmparr[tmpidx++] = l;tmparr[tmpidx++] = r;lines[lineidx++] = line{ l,r };
}inline bool equal(double x, double y) {return fabs(x - y) < eps;
}void discrete() {sort(tmparr, tmparr + tmpidx);int cnt = 0;for (int i = 0; i < tmpidx; i++) {if (i == 0) {dict[tmparr[i]] = ++cnt;continue;}if (tmparr[i] != tmparr[i - 1])dict[tmparr[i]] = ++cnt;}
}signed main() {n = read(); m = read();arr[0].x1 = read();arr[0].y1 = read();int tmpid;int cnt;tmpidx = lineidx = 0;for (cnt = 1; cnt <= n; cnt++) {tmpid = read();arr[tmpid].x1 = read();arr[tmpid].y1 = read();arr[tmpid].x2 = arr[tmpid].x1 + read();arr[tmpid].y2 = arr[tmpid].y1 + read();arr[tmpid].idx = cnt - 1;process(arr[tmpid]);}int optnum;for (int i = 1; i <= m; i++) {qarr[i].opt[0] = read();switch (qarr[i].opt[0]){case 1:tmpid = read();arr[tmpid].x1 = read();arr[tmpid].y1 = read();arr[tmpid].x2 = arr[tmpid].x1 + read();arr[tmpid].y2 = arr[tmpid].y1 + read();arr[tmpid].idx = cnt++ - 1;process(arr[tmpid]);qarr[i].opt[1] = tmpid;break;case 2:qarr[i].opt[1] = read();break;case 3:qarr[i].opt[1] = read();tmparr[tmpidx++] = qarr[i].opt[1];break;default:break;}}discrete();for (int i = 0; i < n; i++) {double l = lines[i].first;double r = lines[i].second;l = dict[l]; r = dict[r];add(l, 1);add(r + 1, -1);}for (int i = 1; i <= m; i++) {if (qarr[i].opt[0] == 1) {int p = qarr[i].opt[1];p = arr[p].idx;double l = lines[p].first;double r = lines[p].second;l = dict[l]; r = dict[r];add(l, 1);add(r + 1, -1);}else if (qarr[i].opt[0] == 2) {int p = qarr[i].opt[1];p = arr[p].idx;double l = lines[p].first;double r = lines[p].second;add(dict[l], -1);add(dict[r] + 1, 1);}else {double p = qarr[i].opt[1];if (ask(dict[p])) { printf("YES\n");}else printf("NO\n");}}return 0;
}

相关文章:

阴影映射(线段树)

实时阴影是电子游戏中最为重要的画面效果之一。在计算机图形学中&#xff0c;通常使用阴影映射方法来实现实时阴影。 游戏开发部正在开发一款 2D 游戏&#xff0c;同时希望能够在 2D 游戏中模仿 3D 游戏的光影效果&#xff0c;请帮帮游戏开发部&#xff01; 给定 x-y 平面上的…...

Docker 容器间通讯

1、虚拟ip/访问 同一网络 安装docker时&#xff0c;docker会默认创建一个内部的桥接网络docker0&#xff0c;每创建一个容器分配一个虚拟网卡&#xff0c;容器之间(包括宿主机)可以根据分配的ip互相访问(ps:其他主机(包括其他主机的容器)无法ping通docker容器ip无法访问&#…...

C语言章节学习归纳--数据类型、运算符与表达式

3.1 C语言的数据类型&#xff08;理解&#xff09; 首先&#xff0c;对变量的定义可以包括三个方面&#xff1a; 数据类型 存储类型 作用域 所谓数据类型是按被定义变量的性质&#xff0c;表示形式&#xff0c;占据存储空间的多少&#xff0c;构造特点来划分的。在C语言中&…...

Centos 7.9 使用 iso 搭建本地 YUM 源

Centos 7.9 使用 iso 搭建本地 YUM 源 1 建立挂载点 [rootlocalhost ~]# mkdir -p /media/cdrom/ 2 创建光盘存储路径 [rootlocalhost ~]# mkdir -p /mnt/cdrom/ 3 上传 CentOS-7-x86_64-Everything-2207-02.iso 到 光盘存储路径 [rootlocalhost ~]# ls /mnt/cdrom/ CentOS-…...

NFT Insider #131:Mocaverse NFT市值破3.5万ETH,The Sandbox 参加NFCsummit

引言&#xff1a;NFT Insider由NFT收藏组织WHALE Members&#xff08;https://twitter.com/WHALEMembers&#xff09;、BeepCrypto &#xff08;https://twitter.com/beep_crypto&#xff09;联合出品&#xff0c;浓缩每周NFT新闻&#xff0c;为大家带来关于NFT最全面、最新鲜、…...

BatBot智慧能源管理平台,更加有效地管理能源

随着能源消耗的不断增加&#xff0c;能源管理已成为全球面临的重要问题。BatBot智慧能源管理作为一种的能源管理技术&#xff0c;促进企业在用能效率及管理有着巨大的提升。 BatBot智慧能源管理是一种基于人工智能技术的能源管理系统&#xff0c;通过智能分析和优化能源使用&…...

医院预约挂号系统微信小程序APP

医院预约挂号小程序&#xff0c;前端后台&#xff08;后台 java spring boot mysql&#xff09; 医院预约挂号系统具体功能介绍&#xff1a;展示医院信息、可以注册和登录&#xff0c; 预约挂号&#xff08;包含各个科室的预约&#xff0c;可以预约每个各个医生&#xff09;&…...

【代码随想录 二叉树】二叉树前序、中序、后序遍历的迭代遍历

文章目录 1. 二叉树前序遍历&#xff08;迭代法&#xff09;2. 二叉树后序遍历&#xff08;迭代法&#xff09;3. 二叉树中序遍历&#xff08;迭代法&#xff09; 1. 二叉树前序遍历&#xff08;迭代法&#xff09; 题目连接 &#x1f34e;因为处理顺序和访问顺序是一致的。所…...

Error:(6, 43) java: 程序包org.springframework.data.redis.core不存在

目录 一、在做SpringBoot整合Redis的项目时&#xff0c;报错&#xff1a; 二、尝试 三、解决办法 一、在做SpringBoot整合Redis的项目时&#xff0c;报错&#xff1a; 二、尝试 给依赖加版本号&#xff0c;并且把版本换了个遍&#xff0c;也不行&#xff0c;也去update过ma…...

Qt 科目一考试系统(有源码)

项目源码和资源&#xff1a;科目一考试系统: qt实现科目一考试系统 一.项目概述 该项目是一个基于Qt框架开发的在线考试系统&#xff0c;主要实现了考试题目的随机抽取、考试时间限制、成绩统计等功能。用户可以通过界面操作进行考试&#xff0c;并查看自己的考试成绩。 二.技…...

在 Visual Studio 2022 (VS2022) 中删除 Git 分支的步骤如下

git branch -r PS \MauiApp1> git push origin --delete “20240523备份” git push origin --delete “20240523备份”...

玩转OpenHarmony智能家居:如何实现开发版“碰一碰”设备控制

一、简介 “碰一碰”设备控制&#xff0c;依托NFC短距通信协议&#xff0c;通过碰一碰的交互方式&#xff0c;将OpenAtom OpenHarmony&#xff08;简称“OpenHarmony”&#xff09;标准系统设备和全场景设备连接起来&#xff0c;解决了应用与设备之间接续慢、传输难的问题&…...

订餐系统总结、

应用层&#xff1a; SpringBoot:快速构建Spring项目&#xff0c;采用“约定大于配置”的思想&#xff0c;简化Spring项目的配置开发。 SpringMvc&#xff1a;Spring框架的一个模块&#xff0c;springmvc和spring无需通过中间整合层进行整合&#xff0c;可以无缝集成。 Sprin…...

【因果推断从入门到精通二】随机实验3

目录 检验无因果效应假说 硬币投掷的特殊性何在&#xff1f; 检验无因果效应假说 无因果效应假说认为&#xff0c;有些人存活&#xff0c;有些人死亡&#xff0c;但接受mAb114治疗而不是ZMapp与此无关。在174例接受mAb14治疗的患者中&#xff0c;113/17464.9%存活了28天&…...

真实案例分享,终端pc直接telnet不到出口路由器。

1、背景信息 我终端pc的网卡地址获取的网关是在核心交换机上&#xff0c;在核心交换机上telnet出口路由器可以实现。 所有终端网段都不能telnet出口路由器&#xff0c;客户希望能用最小的影响方式进行解决。 2、现有配置信息 终端的无线和有线分别在两个网段中&#xff0c;…...

YOLOv8_seg的训练、验证、预测及导出[实例分割实践篇]

实例分割数据集链接,还是和目标检测篇一样,从coco2017val数据集中挑出来person和surfboard两类:链接:百度网盘 请输入提取码 提取码:3xmm 1.实例分割数据划分及配置 1.1实例分割数据划分 从上面得到的数据还不能够直接训练,需要按照一定的比例划分训练集和验证集,并按…...

Linux基础(四):Linux系统文件类型与文件权限

各位看官&#xff0c;好久不见&#xff0c;在正式介绍Linux的基本命令之前&#xff0c;我们首先了解一下&#xff0c;关于文件的知识。 目录 一、文件类型 二、文件权限 2.1 文件访问者的分类 2.2 文件权限 2.2.1 文件的基本权限 2.2.2 文件权限值的表示方法 三、修改文…...

本是梦中人,常作花下客。心中自往来,知我有几个。

我们总是喜欢拿“顺其自然”来敷衍人生道路上的荆棘坎坷&#xff0c;却很少承认&#xff0c;真正的顺其自然&#xff0c; 其实是竭尽所能之后的不强求&#xff0c; 而非两手一摊的不作为。 一花凋零荒芜不了整个春天&#xff0c; 一次挫折也荒废不了整个人生。 多年后&#x…...

创新指南|利用电商产品视频进行渠道营销的最佳策略,不断提升销售额

无论企业的利基市场如何&#xff0c;电商产品视频都已被证明是非常可靠的资产&#xff0c;可以让目标受众了解您所提供的产品——关键功能、展示重要的差异化优势甚至改变大多数营销活动的游戏规则。阅读本文&#xff0c;全面了解电商产品视频如何融入营销推广&#xff0c;以最…...

深度学习之基于YoloV5入侵检测系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景 随着信息技术的飞速发展&#xff0c;网络安全问题日益凸显。入侵检测系统&#xff08;IDS&#xff0…...

Phi-4-mini-reasoning保姆级教学:Web服务健康检查失败的5类根因与对策

Phi-4-mini-reasoning保姆级教学&#xff1a;Web服务健康检查失败的5类根因与对策 1. 问题背景与模型介绍 Phi-4-mini-reasoning 是一款专注于推理任务的文本生成模型&#xff0c;特别擅长处理数学题、逻辑题、多步分析和简洁结论输出。与通用聊天模型不同&#xff0c;它采用…...

Qwen3.5-35B-A3B-AWQ-4bit企业降本增效案例:替代人工审核10万+商品图的自动化方案

Qwen3.5-35B-A3B-AWQ-4bit企业降本增效案例&#xff1a;替代人工审核10万商品图的自动化方案 1. 企业面临的商品图审核挑战 在电商行业&#xff0c;商品图片审核是一项繁重但至关重要的工作。以某大型电商平台为例&#xff0c;每天需要审核超过10万张商品图片&#xff0c;传统…...

Qwen2.5深度微调成果展示|像素剧本圣殿在武侠/赛博朋克题材表现

Qwen2.5深度微调成果展示&#xff5c;像素剧本圣殿在武侠/赛博朋克题材表现 1. 项目概览 像素剧本圣殿&#xff08;Pixel Script Temple&#xff09;是基于Qwen2.5-14B-Instruct深度微调的专业剧本创作工具。这个独特的创作环境将先进的大语言模型能力与8-Bit复古美学完美融合…...

Qwen3.5-9B生产环境实践:高并发请求处理+响应延迟优化策略

Qwen3.5-9B生产环境实践&#xff1a;高并发请求处理响应延迟优化策略 1. 项目概述与核心能力 Qwen3.5-9B是一款拥有90亿参数的开源大语言模型&#xff0c;在多个领域展现出卓越的性能。这个模型特别适合需要处理复杂任务的生产环境&#xff0c;因为它具备以下核心能力&#x…...

OpenClaw多模态技能开发:为Phi-3-vision-128k-instruct增加PDF图表提取功能

OpenClaw多模态技能开发&#xff1a;为Phi-3-vision-128k-instruct增加PDF图表提取功能 1. 为什么需要PDF图表提取能力 上周我在研究一份技术白皮书时遇到了典型痛点——PDF里那些精美的架构图和流程图无法直接复制使用。手动截图再粘贴到文档里不仅效率低下&#xff0c;更重…...

忍者像素绘卷参数详解:CFG值对‘火之意志’风格权重响应敏感度测试

忍者像素绘卷参数详解&#xff1a;CFG值对火之意志风格权重响应敏感度测试 1. 引言&#xff1a;像素艺术与AI的完美融合 忍者像素绘卷是一款基于Z-Image-Turbo深度优化的图像生成工具&#xff0c;它将传统忍者文化与16-Bit复古游戏美学相结合&#xff0c;创造出独特的视觉体验…...

OpenClaw旅行规划专家:Qwen3-14b_int4_awq自动生成行程表与预订提醒

OpenClaw旅行规划专家&#xff1a;Qwen3-14b_int4_awq自动生成行程表与预订提醒 1. 为什么需要AI旅行规划助手 每次计划旅行时&#xff0c;我总会被各种琐事淹没&#xff1a;查天气、比价酒店、确认景点开放时间、安排交通路线……这些重复劳动既耗时又容易出错。直到上个月尝…...

小红书内容保存难题,这款Python工具如何实现一键无水印下载?

小红书内容保存难题&#xff0c;这款Python工具如何实现一键无水印下载&#xff1f; 【免费下载链接】XHS-Downloader 小红书&#xff08;XiaoHongShu、RedNote&#xff09;链接提取/作品采集工具&#xff1a;提取账号发布、收藏、点赞、专辑作品链接&#xff1b;提取搜索结果作…...

从零实现Clock页面置换算法:原理、代码与性能调优实战

1. 为什么需要页面置换算法&#xff1f; 想象你正在玩一个大型开放世界游戏&#xff0c;电脑内存就像你的背包空间。当背包装满时&#xff0c;每次捡新道具都需要先扔掉旧道具——这就是操作系统面临的内存管理问题。Clock算法就是那个帮你智能决定"扔哪件道具"的管家…...

OpenClaw自动化测试:Kimi-VL-A3B-Thinking多模态交互验证框架

OpenClaw自动化测试&#xff1a;Kimi-VL-A3B-Thinking多模态交互验证框架 1. 为什么需要AI驱动的自动化测试 去年接手一个客户端项目时&#xff0c;我遇到了一个典型痛点——每次发版前的手动回归测试需要3个人天。更麻烦的是&#xff0c;UI微调导致的视觉差异很难通过传统断…...