题面

测试要求 Bob 尽可能快地切断 n 根绳子。

所有绳子的端点两两不同,所以共有 2n 个端点。这些端点被捆在一个圆上,等距离分布。我们把这些端点按顺时针方向编号为 1 到 2n。

Bob 每次切割的轨迹是一条直线,可以将所有与这条直线相交的绳子切断,他想知道至少多少次可以切断所有的绳子。

\(n<=2*10^5\)

传送门

题解

先破环成链

我们可以想到,对于原本环上存在的一条线段,我们可以标记一下它两端点在链上的位置

而一条直线穿过了此线段,则说明此线段两端点的弧中一定存在一个Bod用太极剑划出的直线的端点

所以我们只要保证:

圆上两个标记相同的点之间一定要有一个断点

考虑如何贪心:

对于两个标记相同的点,肯定将断点设在靠右的端点上会更优,因为这样能够断开更多其他标记相同的点

此外我们还需要找到最开始的断点

(这图我盗的,图片作者抱歉)



比如上图中,有三个断点,却只需要一条直线

仔细想想就能知道断点枚举的顺序影响了最终结果

因为端点之间必定有端点,所以较短的端点距离会比较长的端点距离更好枚举作为断点

所以我们直接找到最小的端点距离,枚举初始断点

最后

我们来想想看它的复杂度,设最小的端点距为d

所以之后每个端点之间必定会大于间隙d,而断点的选择会是下一个还未被断开的线段的靠右的端点,所以关于找到下一个断点,可以直接在此位置+d,再一一向后枚举

所以总复杂度为:

\(O(d(枚举初始节点)*(2*n/d)(对于每个初始节点向后递推位置))\)

代码

#include<bits/stdc++.h>
using namespace std;
#define re register
#define in inline
#define ll long long
#define get getchar()
in int read()
{
int t=0,x=1;char ch=get;
while((ch<'0'||ch>'9')&&ch!='-')ch=get;
if(ch=='-')x=-1,ch=get;
while(ch<='9'&&ch>='0')t=t*10+ch-'0',ch=get;
return x*t;
}
const int _=8e5+5;
int n;
struct edge{
int l,r;
}a[_];
int to[_];
in int dis(int x,int y)
{
return min(y-x,2*n-y+x);
}
int main()
{
n=read();
int minx=0x3f3f3f3f,xx;
for(re int i=1;i<=n;i++)
{
a[i].l=read(),a[i].r=read();
if(a[i].l>a[i].r) swap(a[i].l,a[i].r);
to[a[i].r]=a[i].l;
to[a[i].l+2*n]=a[i].r;
to[a[i].r+2*n]=a[i].l+2*n;//倍长区间,标记每个区间右端点对应的左端点
if(minx>dis(a[i].l,a[i].r)){
minx=dis(a[i].l,a[i].r);
xx=i; //记录最小距离的区间
}
}
int st,en,ans=0;
if(a[xx].r-a[xx].l==minx)
st=a[xx].l,en=a[xx].r;
else en=a[xx].l+2*n,st=a[xx].r; //标记最小距离区间起始点与结束点
int len=dis(a[xx].l,a[xx].r);
for(re int i=st;i<=en;i++)
{
int last=i;ans=0;//last记录上一个断点
for(re int j=i+len;j<i+2*n;j++)
if(to[j]>last) ans++,last=j,j+=len; //判断条件是如果当前区间不会被上一个断点断开,则新开一个断点
}
cout<<(ans)/2+1<<endl;
return 0;
}

LuoguP4704 太极剑的更多相关文章

  1. 洛谷P4704 太极剑(乱搞)

    题意 题目链接 Sol 不会正解 写了发暴力过了,貌似跑的还挺快?.. // luogu-judger-enable-o2 // luogu-judger-enable-o2 #include< ...

  2. [luoguT30208]太极剑

    题面在这里 description 在一个圆环上给出\(n\)条端点在圆环上的绳子, 每次在圆环上切割的轨迹是一条直线,可以将可以将所有与这条直线相交的绳子切断. 求切割次数的最小值. data ra ...

  3. 洛谷 P4704 太极剑【贪心】

    首先考虑分割线能分割一条线当且仅当分割线一个端点在这条线的ab中间,另一端点在外面,也就是分割线对应的一条弧不能同时有这条线的两个端点 每条线的两端点都染同色,然后分段,一段里面颜色互不相同,分割线就 ...

  4. Java 征途:行者的地图

    前段时间应因缘梳理了下自己的 Java 知识体系, 成文一篇望能帮到即将走进或正在 Java 世界跋涉的程序员们. 第一张,基础图 大约在 2003 年我开始知道 Java 的(当时还在用 Delph ...

  5. 记一次.NET代码重构

    好久没写代码了,终于好不容易接到了开发任务,一看时间还挺充足的,我就慢慢整吧,若是遇上赶进度,基本上直接是功能优先,完全不考虑设计.你可以认为我完全没有追求,当身后有鞭子使劲赶的时候,神马设计都是浮云 ...

  6. 【道德经】漫谈实体、对象、DTO及AutoMapper的使用

    写在前面 实体和值对象 实体和对象 故常无欲以观其妙,常有欲以观其徼 初始实体和演化实体 代码中的DTO AutoMapper实体转换 后记 实体(Entity).对象(Object).DTO(Dat ...

  7. NET代码重构

    记一次.NET代码重构   好久没写代码了,终于好不容易接到了开发任务,一看时间还挺充足的,我就慢慢整吧,若是遇上赶进度,基本上直接是功能优先,完全不考虑设计.你可以认为我完全没有追求,当身后有鞭子使 ...

  8. [转]Java 征途:行者的地图

    前段时间应因缘梳理了下自己的 Java 知识体系, 成文一篇望能帮到即将走进或正在 Java 世界跋涉的程序员们. 第一张,基础图 大约在 2003 年我开始知道 Java 的(当时还在用 Delph ...

  9. Java 征途:行者的地图 (转)

    http://www.cnblogs.com/mindwind/p/5251430.html Java 征途:行者的地图   前段时间应因缘梳理了下自己的 Java 知识体系, 成文一篇望能帮到即将走 ...

随机推荐

  1. myisamchk是用来做什么的?MyISAM Static和MyISAM Dynamic有什么区别?

    myisamchk是用来做什么的? 它用来压缩MyISAM[歌1] 表,这减少了磁盘或内存使用. MyISAM Static和MyISAM Dynamic有什么区别? 在MyISAM Static上的 ...

  2. 从源码角度理解Java设计模式——装饰者模式

    一.饰器者模式介绍 装饰者模式定义:在不改变原有对象的基础上附加功能,相比生成子类更灵活. 适用场景:动态的给一个对象添加或者撤销功能. 优点:可以不改变原有对象的情况下动态扩展功能,可以使扩展的多个 ...

  3. SQL Server 子查询遇到的坑

    这两天改 Bug 时使用 Sql Server 的子查询遇到了一些问题,特此记录一下,之前用 MySQL 比较多,按照 MySQL 的语法其实是没有问题的. 以下面这张表为例: 执行以下 SQL: s ...

  4. Centos-切换用户身份-su

    su 切换用户身份 相关选项 - 加载相应用户下环境变量 -c   使用某个身份执行一个指令 -m  改变用户身份不改变环境变量 切换为超级用户 su - 普通用户切换为超级用户需要输入密码,超级用户 ...

  5. Spring Cloud系列(二):Eureka应用详解

    一.注册中心 1.注册中心演变过程 2.注册中心必备功能 ① 服务的上线 ② 服务的下线 ③ 服务的剔除 ④ 服务的查询 ⑤ 注册中心HA ⑥ 注册中心节点数据同步 ⑦ 服务信息的存储,比如mysql ...

  6. python中的filter、map、reduce、apply用法总结

    1. filter 功能: filter的功能是过滤掉序列中不符合函数条件的元素,当序列中要删减的元素可以用某些函数描述时,就应该想起filter函数. 调用: filter(function,seq ...

  7. 【题解】 [EZEC-4]求和

    对于百分之十的数据:随便过. 下面推式子: \[\sum_{i=1}^n\sum_{j=1}^n\gcd(i,j)^{i+j} \] \[=\sum_{d=1}^n\sum_{i=1}^n\sum_{ ...

  8. JavaScript事件对象属性e.target和this的区别

    前言: Event对象代表事件的状态,比如事件在其中发生的元素.键盘按键的状态.鼠标的位置.鼠标按钮的状态. 事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象eve ...

  9. shell-变量的数值运算let内置命令

    1. let命令的用法 格式: let 赋值表达式 [注]let赋值表达式功能等同于:((赋值表达式))  范例1:给自变量i加8 [root@1-241 scripts]# i=2 [root@1- ...

  10. 推荐一款IDEA神器!一键查看Java字节码以及其他类信息

    由于后面要分享的一篇文章中用到了这篇文章要推荐的一个插件,所以这里分享一下.非常实用!你会爱上它的! 开始推荐 IDEA 字节码查看神器之前,先来回顾一下 Java 字节码是啥. 何为 Java 字节 ...