题意:

给出n个线段组成的集合,第i个线段用 \(\{l_i, r_i\}\) 表示线段从坐标轴的点\(l_i\)横跨到点\(r_i\)。现在你可以删除其中的一些线段,使得剩下的线段组成的集合中至少存在一个线段满足:这个线段与所有其他线段都相交。现在问你最少需要删除几条边可以得到满足要求的线段集合。

思路:

我们枚举每个线段,让这个线段能够与所有其他线段相交,这时候我们只需要算出不和这个边相交的线段的个数。算这个的方法也很简单,可以想一下什么情况下两个线段 \(\{l_1, r_1\}\) \(\{l_2, r_2\}\) 不相交,也就是 \(l_2 > r1\) 或者 \(r_2 < l_1\) 的情况下,两个边就不会相交。所以我们可以用两个数组来分别存储边的\(l\) 和\(r\),排序之后,就可以用二分来快速找到不与当前枚举的边相交的边的个数。

小注:

之前有看其他博主写的博客,有提到二分比较难写,主要是因为没有善用\(lower\_bound\)和\(upper\_bound\)。

AC代码:

#include <cstdio>
#include <algorithm> #define pii pair<int, int>
#define fr first
#define sc second const int maxn = 2e5 + 5;
const int inf = 0x3f3f3f3f; std::pii a[maxn];
int l[maxn], r[maxn]; int main () {
int T, n;
scanf ("%d", &T);
while (T--) {
scanf ("%d", &n);
for (int i = 0; i < n; i++) {
scanf ("%d %d", &a[i].fr, &a[i].sc);
l[i] = a[i].fr;
r[i] = a[i].sc;
}
std::sort (l, l + n);
std::sort (r, r + n);
int ans = inf;
for (int i = 0; i < n; i++) {
int tot = 0;
tot = 0;
tot += (int)(std::lower_bound(r, r + n, a[i].fr) - r);
tot += n - (int)(std::upper_bound(l, l + n, a[i].sc) - l);
ans = std::min (ans, tot);
}
printf ("%d\n", ans);
}
return 0;
}

这题一开始没想到那么简洁的做法,最开始用线段树维护不和当前枚举的线段相交的个数,结果。。。T了。

杀鸡用牛刀超时未AC代码:

#include <cstdio>
#include <cstring>
#include <algorithm> #define pii pair<int, int>
#define mp(a, b) make_pair(a, b)
#define fr first
#define sc second const int maxn = 2e5 + 5;
const int inf = 0x3f3f3f3f; std::pii in[maxn], num[maxn];
int lisan[maxn << 1], tot_lisan = 1; class seg_tree {
public:
int tree[maxn << 2]; void init() {
memset (tree, 0, sizeof tree);
} void push_up (int p) {
tree[p] = tree[p << 1] + tree[p << 1 | 1];
} void update (int p, int l, int r, int idx) {
if (l == r) {
tree[p]++;
} else {
int mid = (l + r) >> 1;
if (idx <= mid) {
update (p << 1, l, mid, idx);
} else {
update (p << 1 | 1, mid + 1, r, idx);
}
push_up(p);
}
} int query (int p, int l, int r, int ql, int qr) {
if (r < ql || l > qr) {
return 0;
} else if (l >= ql && r <= qr) {
return tree[p];
} else {
int mid = (l + r) >> 1;
int ans = 0;
ans += query (p << 1, l, mid, ql, qr);
ans += query (p << 1 | 1, mid + 1, r, ql, qr);
return ans;
}
}
}t1, t2; int main () {
int T, n;
scanf ("%d", &T);
while (T--) {
t1.init();
t2.init();
tot_lisan = 1;
memset (num , 0, sizeof num);
scanf ("%d", &n);
for (int i = 0; i < n; i++) {
int l, r;
scanf ("%d %d", &l, &r);
in[i] = std::mp(l, r);
lisan[tot_lisan++] = l;
lisan[tot_lisan++] = r;
}
std::sort (lisan, lisan + tot_lisan);
std::sort (in, in + n);
tot_lisan = (int)(std::unique(lisan, lisan + tot_lisan) - lisan);
for (int i = 0; i < n; i++) {
int pl = (int)(std::lower_bound(lisan, lisan + tot_lisan, in[i].fr) - lisan);
int pr = (int)(std::lower_bound(lisan, lisan + tot_lisan, in[i].sc) - lisan);
num[i].fr = pl;
num[i].sc = pr;
t1.update (1, 0, tot_lisan, pl);
t2.update (1, 0, tot_lisan, pr);
}
int ans = inf;
for (int i = 0; i < n; i++) {
int pl = num[i].fr;
int pr = num[i].sc;
int tot = 0;
tot += t1.query (1, 0, tot_lisan, pr + 1, tot_lisan);
tot += t2.query (1, 0, tot_lisan, 0, pl - 1);
ans = std::min (ans, tot);
}
printf ("%d\n", ans);
}
return 0;
}

CF1462-F. The Treasure of The Segments的更多相关文章

  1. Codeforces Round #690 (Div. 3)

    第一次 ak cf 的正式比赛,不正式的是寒假里 div4 的 Testing Round,好啦好啦不要问我为什么没有 ak div4 了,差一题差一题 =.= 不知不觉已经咕了一个月了2333. 比 ...

  2. Mysql_以案例为基准之查询

    查询数据操作

  3. Educational Codeforces Round 6 F. Xors on Segments 暴力

    F. Xors on Segments 题目连接: http://www.codeforces.com/contest/620/problem/F Description You are given ...

  4. Codeforces Round #524 (Div. 2) F. Katya and Segments Sets(主席树)

    https://codeforces.com/contest/1080/problem/F 题意 有k个区间,区间的种类有n种,有m个询问(n,m<=1e5,k<=3e5),每次询问a,b ...

  5. Codeforces Round #523 (Div. 2) F. Katya and Segments Sets (交互题+思维)

    https://codeforces.com/contest/1061/problem/F 题意 假设存在一颗完全k叉树(n<=1e5),允许你进行最多(n*60)次询问,然后输出这棵树的根,每 ...

  6. hdu 5446 Unknown Treasure 卢卡斯+中国剩余定理

    Unknown Treasure Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Other ...

  7. POJ2594 Treasure Exploration

    Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 8193   Accepted: 3358 Description Have ...

  8. codeforces 677D D. Vanya and Treasure(二维线段树)

    题目链接: D. Vanya and Treasure time limit per test 1.5 seconds memory limit per test 256 megabytes inpu ...

  9. BZOJ2101: [Usaco2010 Dec]Treasure Chest 藏宝箱

    2101: [Usaco2010 Dec]Treasure Chest 藏宝箱 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 327  Solved:  ...

随机推荐

  1. 关于SSRF与CSRF漏洞的解释

    目录 SSRF服务端请求伪造(外网访问内网) 1.SSRF形成原因 2.利用SSRF漏洞的目的 3.SSRF漏洞的用途 4.SSRF漏洞的特性 实例 5.如何挖掘SSRF漏洞 6.常用SSRF去做什么 ...

  2. 【Python】简单的脚本,轻松批量修改文件名称

    使用python脚本,批量修改文件夹名称 先创建一些没用的案例文件 import os #创建新文件夹 dir = os.makedirs('D:\\SomeThing\\testfile') #将文 ...

  3. 【Linux】rsync模板配置问题

    ------------------------------------------------------------------------------------------------- | ...

  4. 查询数据库v$session时报部分多维元组字元

    在查询v$session视图时,出现如下图报错,基本原因是用plsql dev时使用汉字打开新标签,导致v$session action栏位出现乱码 解决方法: select SID,SERIAL#, ...

  5. 盼望着,盼望着。它终于来了!!!剪辑Windows PC测试版!

    盼望着,盼望着.它终于来了!!!剪辑Windows PC测试版! 喜欢短视频抖音的小伙伴们,是不是都对手机抖音剪映操作不是很满意.期待WINDOWS电脑版剪映的来临.在此之前只有MAC版本,不能满足广 ...

  6. 从synchronized和lock区别入手聊聊java锁机制

    写这篇文章之前,我去百度了一下啥叫锁,百度百科上写道:置于可启闭的器物上,以钥匙或暗码开启.确实我们一般理解的锁就是门锁,密码锁,但是在计算机科学中,锁又是啥,说实话,这个问题我也思考了很久,也没法很 ...

  7. 电脑微信电脑PC 多开/防撤回 补丁

    简介 经常使用微信电脑版的用户都会发现一个蛋疼的事情,那就是微信PC版不支持多开,也就是不能同时登陆多个账号,这对于需要在电脑上登陆多个微信账号的朋友来说肯定是极其的不方便.另外有的时候别人撤回了一些 ...

  8. [从源码学设计] Flume 之 memory channel

    [从源码学设计] Flume 之 memory channel 目录 [从源码学设计] Flume 之 memory channel 0x00 摘要 0x01 业务范畴 1.1 用途和特点 1.2 C ...

  9. 陈思淼:阿里6个月重写Lazada,再造“淘宝”的技术总结

    小结: 1. 所谓的中台技术,就是从 IDC,网络,机房,操作系统,中间件,数据库,算法平台,数据平台,计算平台,到业务平台,每一层都有清晰的定义和技术产品. 具体来看,首先,集团技术的分层和每层的产 ...

  10. .Vue-router跳转和location.href有什么区别

    使用location.href='/url'来跳转,简单方便,但是刷新了页面:使用history.pushState('/url'),无刷新页面,静态跳转:引进router,然后使用router.pu ...