【线段树二分】第十三届蓝桥杯省赛C++ A组/研究生组 Python 研究生组《扫描游戏》(C++)

【题目描述】

有一根围绕原点 O 顺时针旋转的棒 OA,初始时指向正上方(Y 轴正向)。

在平面中有若干物件,第 i 个物件的坐标为(x_{i},y_{i}),价值为 z_{i}

当棒扫到某个物件时,棒的长度会瞬间增长 z_{i},且物件瞬间消失(棒的顶端恰好碰到物件也视为扫到),如果此时增长完的棒又额外碰到了其他物件,也按上述方式消去(它和上述那个点视为同时消失)。

如果将物件按照消失的时间排序,则每个物件有一个排名,同时消失的物件排名相同,请输出每个物件的排名,如果物件永远不会消失则输出 −1。

所有物品坐标两两不同。

【输入格式】

输入第一行包含两个整数 n、L,用一个空格分隔,分别表示物件数量和棒的初始长度。

接下来 n 行每行包含第三个整数x_{i},y_{i}z_{i}

【输出格式】

输出一行包含 n 整数,相邻两个整数间用一个空格分隔,依次表示每个物件的排名。

【数据范围】

对于 30% 的评测用例,1≤n≤500;
对于 60% 的评测用例,1≤n≤5000;
对于所有评测用例,1≤n≤200000,−10^{9} ≤ x_{i},y_{i} ≤ 10^{9},1 ≤ L,z_{i} ≤ 10^{9}

【输入样例】

5 2
0 1 1
0 3 2
4 3 5
6 8 1
-51 -33 2

【输出样例】

1 1 3 4 -1

【思路】

题解来源:AcWing 4649. 扫描游戏 - AcWing

【代码】

#include <bits/stdc++.h>
typedef long long LL;
const int N = 2e5 + 10;
const __int128 INF = 1e38;
int n, ans[N], idx;
__int128 len;template <typename T> //快读模板
inline T fastread(T &x)
{x = 0;T w = 1;char ch = 0;while (ch < '0' || ch > '9'){if (ch == '-')w = -1;ch = getchar();}while (ch >= '0' && ch <= '9'){x = x * 10 + (ch - '0');ch = getchar();}return x = x * w;
}struct point
{LL x, y, z;int id;
} a[N];
int Quadrant(point a) //因为棒是顺时针旋转,我们这里把正常意义下的二四象限调换一下
{if (a.x >= 0 && a.y > 0)return 1;if (a.x > 0 && a.y <= 0)return 2;if (a.x <= 0 && a.y < 0)return 3;elsereturn 4;
}
LL cross(point a, point b) //求叉积
{return a.x * b.y - a.y * b.x;
}
bool cmp(point a, point b) //极角排序,排序完后,所有点就按顺时针排好了
{if (Quadrant(a) == Quadrant(b)){if (cross(a, b) == 0) //当极角相同,我们这里按照距离原点距离的平方来排序return a.x * a.x + a.y * a.y < b.x * b.x + b.y * b.y;return cross(a, b) < 0;}return Quadrant(a) < Quadrant(b);
}//线段树
struct
{__int128 minv;
} seg[N * 4]; //线段树维护的是点到原点的距离的区间最小值
void pushup(int id)
{seg[id].minv = std::min(seg[id << 1].minv, seg[id << 1 | 1].minv);
}
void build(int id, int l, int r)
{if (l == r)seg[id].minv = a[l].x * a[l].x + a[l].y * a[l].y;else{int mid = l + r >> 1;build(id << 1, l, mid);build(id << 1 | 1, mid + 1, r);pushup(id);}
}
void change(int id, int l, int r, int pos, __int128 val)
{if (l == r)seg[id].minv = val;else{int mid = l + r >> 1;if (pos <= mid)change(id << 1, l, mid, pos, val);elsechange(id << 1 | 1, mid + 1, r, pos, val);pushup(id);}
}
int search(int id, int l, int r, int ql, int qr, __int128 val) //线段树上二分模板
//返回[ql,qr]这段区间里从左至右第一个小于等于val的元素的下标,不存在就返回-1
{if (l == ql && r == qr) //此时的区间正好是询问区间{if (seg[id].minv > val) //如果整个区间的最小值都大于val,直接返回-1return -1;else{if (l == r)return l;int mid = l + r >> 1;if (seg[id << 1].minv <= val) //如果左儿子里有这样的元素,直接进入左儿子即可return search(id << 1, l, mid, ql, mid, val);else //否则进入右儿子return search(id << 1 | 1, mid + 1, r, mid + 1, qr, val);}return seg[id].minv;}int mid = l + r >> 1;if (qr <= mid)return search(id << 1, l, mid, ql, qr, val);else if (ql > mid)return search(id << 1 | 1, mid + 1, r, ql, qr, val);else{int pos = search(id << 1, l, mid, ql, mid, val);if (pos == -1)return search(id << 1 | 1, mid + 1, r, mid + 1, qr, val);elsereturn pos;}
}
signed main()
{// 注意用了快读就不能关闭流同步,不然大概率会炸fastread(n), fastread(len);for (int i = 1; i <= n; ++i) //初始化ans数组ans[i] = -1;for (int i = 1; i <= n; ++i){fastread(a[i].x), fastread(a[i].y), fastread(a[i].z);a[i].id = i;}std::sort(a + 1, a + n + 1, cmp);build(1, 1, n);int last = 0;     // last维护上一个扫到的点int rank = 0;     // rank记录扫到点的排名int lastrank = 0; // 维护lastrank主要是为了处理有几个点极角相同的特殊情况,根据题意它们的排名相同while (true){int idx = -1;if (last + 1 <= n) //一定要记得这句ifidx = search(1, 1, n, last + 1, n, len * len);if (idx != -1)len += a[idx].z;else{if (last >= 2) //一定要记得这句ifidx = search(1, 1, n, 1, last - 1, len * len);if (idx != -1)len += a[idx].z;}if (idx == -1) //没能找到可以划到的点,退出死循环break;change(1, 1, n, idx, INF); //对于扫过的点,我们可以把它单点修改成无穷大,等价于它消失了if (last == 0)ans[a[idx].id] = ++rank, lastrank = rank;else{if (Quadrant(a[last]) == Quadrant(a[idx]) && cross(a[last], a[idx]) == 0) //该点和上一个点是同时被扫到的,所以排名要一样ans[a[idx].id] = lastrank, ++rank;elseans[a[idx].id] = ++rank, lastrank = rank;}last = idx;}for (int i = 1; i <= n; ++i)printf("%d ", ans[i]);printf("\n");return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/568809.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nexus3 Docker 私有仓库

Nexus3 Docker 私有仓库 安装并部署 Nexus3 $ docker search nexus3$ docker pull sonatype/nexus3$ mkdir /home/tester/data/docker/nexus3/sonatype-work $ sudo chown -R 200 /home/tester/data/docker/nexus3/sonatype-work$ docker run -d --namenexus3 \ --restartalw…

2024年蓝牙耳机怎么选?五大爆火真无线蓝牙耳机推荐大公开!

​随着科技的进步&#xff0c;越来越多的用户倾向选择无线蓝牙耳机&#xff0c;摆脱有线耳机的束缚&#xff0c;享受更加自由的音乐体验。为了帮助大家选购到适合自己的蓝牙耳机&#xff0c;我整理了一些目前市面上我个人认为性能优异的款式&#xff0c;与大家分享。 一、蓝牙耳…

Linux(centos7)部署hadoop集群

部署环境要求:已完成JDK环境部署、配置完成固定IP、SSH免费登录、防火墙关闭等。 1、下载、上传主机 官网:https://hadoop.apache.org 2、解压缩、创建软连接 解压: tar -zxvf hadoop-3.3.6.tar.gz软连接: ln -s /usr/local/apps/hadoop-3.3.6 hadoop3、文件配置 hadoo…

uniapp的配置文件、入口文件、主组件、页面管理部分

pages.json 配置文件&#xff0c;全局页面路径配置&#xff0c;应用的状态栏、导航条、标题、窗口背景色设置等 main.js 入口文件&#xff0c;主要作用是初始化vue实例、定义全局组件、使用需要的插件如 vuex&#xff0c;注意uniapp无法使用vue-router&#xff0c;路由须在pag…

【Java程序设计】【C00370】基于(JavaWeb)Springboot的公司进存销管理系统(有论文)

TOC 博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;已经做了六年的毕业设计程序开发&#xff0c;开发过上千套毕业设计程序&#xff0c;博客中有上百套程序可供参考&#xff0c;欢迎共同交流学习。 项目简介 项目获取 &#x1f345;文末点击卡片…

javascript三要素核验身份证号、姓名和人像是否匹配的身份证实名认证接口

在开发的过程中&#xff0c;总会用到各种各样的API接口来实现各种各样的功能。互联网信息时代&#xff0c;为确保注册用户身份信息的正确性&#xff0c;无论是手机端还是电脑端应用都需要进行实名认证来防止虚假身份的使用&#xff0c;维护公共利益和个人权益的安全&#xff0c…

基于前端技术实现的全面预算编制系统

前言 在现代商业环境中&#xff0c;预测销售数据和实际成本是每个公司CEO和领导都极为重视的关键指标。然而&#xff0c;由于市场的不断变化&#xff0c;准确地预测和管理这些数据变得愈发具有挑战性。为了应对这一挑战&#xff0c;建立一个高效的系统来管理和审查销售数据的重…

hbuilderx打包苹果证书获取步骤

简介&#xff1a; 目前app开发&#xff0c;很多企业都用H5框架来开发&#xff0c;而uniapp又是这些h5框架里面最成熟的&#xff0c;因此hbuilderx就成为了开发者的首选。然而,打包APP是需要证书的&#xff0c;那么这个证书又是如何获得呢&#xff1f; 生成苹果证书相对复杂一些…

操作系统:进程间的通信

进程间通信方式 管道 单向传输&#xff0c;先进先出&#xff0c;容量较小&#xff0c;效率低 匿名管道 特点 作用于父子进程间只能保持一个读端一个写端生命周期应当保持一致 管道只剩下读端时会进入非阻塞状态&#xff0c;只剩下写端的时候写满然后阻塞等待读端读数据 …

flask_restful规范返回值之参数设置

设置重命名属性和默认值 使用 attribute 配置这种映射 , 比如&#xff1a; fields.String(attributeusername) 使用 default 指定默认值&#xff0c;比如&#xff1a; fields.String(defaultsxt) from flask import Flask,render_template from flask_restful import A…

商城小程序项目实现监控的可观测性最佳实践

前言 微信小程序是一种轻量级的应用程序&#xff0c;用户可以在微信内直接使用&#xff0c;无需下载安装。它具有独立的开发框架和生态系统&#xff0c;支持丰富的功能和交互&#xff0c;包括社交、购物、服务等。 观测云对微信小程序的监控能够实时收集性能指标、错误日志和…

AIGC,ChatGPT,Prompt 万能提示词

AIGC ChatGPT 职场案例 AI 绘画 与 短视频制作 PowerBI 商业智能 68集 Mysql 8.0 54集 Oracle 21C 142集 Office 2021实战应用 Python 数据分析实战&#xff0c; ETL Informatica 数据仓库案例实战 51集 Excel 2021实操 100集&#xff0c; Excel 2021函数大全 80集 Excel 2021…