Touching segments(数据结构)
Problem Statement
Your Maths professor is a very nice guy, but he sometimes comes up with not so funny tasks. Today is one such day. The professor drew a bunch of parallel line segments on the board and asked the following question: "How many of these segments can be touched, even on their edges, by exactly two lines perpendicular to them?"
After a few seconds, he spoke again: "Let's make it more interesting. I will give you the starting and the ending points of N segments over the X's axis; today's homework will be to answer the question I asked you above for any set of such segments". Right after the professor's words, one guy asked: "Is there any restriction over the segments' location?", and the professor replied: "Not really, they are just segments, so they can overlap in all the ways you may imagine."
Everybody started thinking of the weird and unexpected task, without getting a convincing result. Some time later, the class got over and before leaving the classroom, the professor said: "Just to take this to the ultimate limits, your final qualification will depend entirely on this task. Good luck and please, don't try to cheat, I will know if you try to do so." So, that was it! Your final Maths qualification was hooked to some play on segments stuff.
Input Format
Input consists of several test cases. The first line in the input is an integer, T, denoting the number of test cases. T test cases follow, each one with the following format:
A single line with an integer, N, denoting the number of segments.
N lines, each defining a segment with two integers, a and b, separated by a single white space, meaning that there is a segment going from a to b.
Constraints
1≤T≤5
1≤N≤105
0≤a<b≤109Output Format
For each test case the output should follow the following format:
- A single line with "Case #: answer" (without the quotes) where # is the serial number of the current test case (start the numbering by 1) and answer is the maximum number of segments you can touch as described above.
See the sample output for more details.
Sample Input
4
5
2 3
1 3
1 5
3 4
4 5
5
1 2
1 3
2 3
1 4
1 5
4
1 5
1 6
1 7
8 10
3
1 2
3 4
5 6
Sample Output
Case 1: 5
Case 2: 5
Case 3: 4
Case 4: 2
Explanation
- Case 1: We will draw two lines (parallel to Y-axis) crossing X-axis at point 2 and 4. These two lines will touch all the five segments.
- Case 2: We can touch all the points even with one line crossing X-axis at 2.
- Case 3: We will draw first line at any point in range [1,5] so that it can touch first three lines. We will draw second line crossing X-axis at any of the points in range [8,10] and it will touch the last line.
- Case 4: It is not possible to touch more than two lines in this case.
好题一枚。
AC代码:
#include <cmath>
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; const int MAX_N = ; struct SegTree {
int val[MAX_N << ], lzy[MAX_N << ];
#define lson(x) (x<<1)
#define rson(x) ((x<<1) | 1) void build() {
memset(val, , sizeof(val));
memset(lzy, , sizeof(lzy));
} void pushDown(int rt) {
if (lzy[rt]) {
val[lson(rt)] += lzy[rt];
lzy[lson(rt)] += lzy[rt];
val[rson(rt)] += lzy[rt];
lzy[rson(rt)] += lzy[rt];
lzy[rt] = ;
}
} void pushUp(int rt) {
val[rt] = max(val[lson(rt)], val[rson(rt)]);
} void update(int rt, int l, int r, int ql, int qr, int v) {
if (l >= ql && r <= qr) {
val[rt] += v;
lzy[rt] += v;
} else {
pushDown(rt);
int mid = (l + r) >> ;
if (ql <= mid) update(lson(rt), l, mid, ql, qr, v);
if (qr > mid) update(rson(rt), mid+, r, ql, qr, v);
pushUp(rt);
}
} int query(int rt, int l, int r, int ql, int qr) {
if (l >= ql && r <= qr) {
return val[rt];
} else {
pushDown(rt);
int mid = (l + r) >> ;
int res = ;
if (ql <= mid) res = max(res, query(lson(rt), l, mid, ql, qr));
if (qr > mid) res = max(res, query(rson(rt), mid+, r, ql, qr));
return res;
}
} }st; int l[MAX_N], r[MAX_N];
int ll[MAX_N], rr[MAX_N];
vector<int> b[MAX_N], e[MAX_N]; // segments begins at $i or ends at $i int main(void) {
int T, cas = ;
scanf("%d", &T);
while (T--) {
int N;
scanf("%d", &N);
vector<int> arr;
for (int i = ; i < N; i++) {
scanf("%d %d", l+i, r+i);
arr.push_back(l[i]);
arr.push_back(r[i]);
} sort(begin(arr), end(arr));
int m = unique(arr.begin(), arr.end()) - arr.begin();
for (int i = ; i < m; i++) {
b[i].clear(); e[i].clear();
} st.build();
for (int i = ; i < N; i++) {
ll[i] = lower_bound(begin(arr), begin(arr)+m, l[i]) - begin(arr);
rr[i] = lower_bound(begin(arr), begin(arr)+m, r[i]) - begin(arr);
b[ll[i]].push_back(i);
e[rr[i]].push_back(i);
st.update(, , m-, ll[i], rr[i], );
} int cnt = , ans = ;
for (int i = ; i < m; i++) {
for (const int &it : b[i]) {
st.update(, , m-, ll[it], rr[it], -);
++cnt;
}
ans = max(ans, cnt + st.query(, , m-, , m-));
for (const int &it : e[i]) {
st.update(, , m-, ll[it], rr[it], -);
--cnt;
}
}
printf("Case %d: %d\n", cas++, ans);
} return ;
}
Touching segments(数据结构)的更多相关文章
- lucene底层数据结构——FST,针对field使用列存储,delta encode压缩doc ids数组,LZ4压缩算法
参考: http://www.slideshare.net/lucenerevolution/what-is-inaluceneagrandfinal http://www.slideshare.ne ...
- ATS缓存数据结构
ATS缓存数据结构 HttpTunnel类 数据传输驱动器(data transfer driver),包含一个生产者(producer)集合,每个生产者连接到一个或是多个消费者(comsumer). ...
- 数据结构之ConcurrentHashMap
并发编程实践中,ConcurrentHashMap是一个经常被使用的数据结构,相比于Hashtable以及Collections.synchronizedMap(),ConcurrentHashMap ...
- 434. Number of Segments in a String 字符串中的单词个数
[抄题]: Count the number of segments in a string, where a segment is defined to be a contiguous sequen ...
- java 的ConcurrentHashMap底层数据结构
集合是编程中最常用的数据结构.而谈到并发,几乎总是离不开集合这类高级数据结构的支持.比如两个线程需要同时访问一个中间临界区(Queue),比如常会用缓存作为外部文件的副本(HashMap).这篇文章主 ...
- Codeforces 976C Nested Segments
题面: 传送门 C. Nested Segments Input file: standard input Output file: standard output Time limit: 2 secon ...
- 多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)
前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...
- 一起学 Java(三) 集合框架、数据结构、泛型
一.Java 集合框架 集合框架是一个用来代表和操纵集合的统一架构.所有的集合框架都包含如下内容: 接口:是代表集合的抽象数据类型.接口允许集合独立操纵其代表的细节.在面向对象的语言,接口通常形成一个 ...
- 深入浅出Redis-redis底层数据结构(上)
1.概述 相信使用过Redis 的各位同学都很清楚,Redis 是一个基于键值对(key-value)的分布式存储系统,与Memcached类似,却优于Memcached的一个高性能的key-valu ...
随机推荐
- 树上思维题——cf1060E
只要算每条路径的贡献即可 显然长度为偶数的贡献是len/2 长度为奇数的贡献是(len+1)/2 所以结果就是(sum+tot)/2 sum:路径总长 tot:奇数路径数量 怎么求奇数路径数量:只有深 ...
- System.Clollections.IEnumerable.cs
ylbtech-System.Clollections.IEnumerable.cs 1.程序集 mscorlib, Version=4.0.0.0, Culture=neutral, PublicK ...
- Python flask 构建微电影视频网站✍✍✍
Python flask 构建微电影视频网站 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课程本身没问题,大 ...
- NEERC 1999 Divisibility /// 同余DP oj22640
题目大意: 输入n,m: ( 1 ≤ N ≤ 10000, 2 ≤ M ≤ 100 ) 接下来n个数:Each integer is not greater than 10000 by it's ab ...
- C++自己用模板减少工作量
今天写代码,遇到这样一个类似如下的需求: auto componentClassSavedByPLC = std::make_shared<ComponentClassSavedByPLC> ...
- UMP系统功能 容灾
- 一个页面上调用多个setInterval失效解决办法(使用于同一时间间隔)
将方法封装在一起,只调用一个setInterval window.setInterval( function () { $.ajax({ type: "GET", url: '/M ...
- Java 生成pdf表格文档
最近在工作做一个泰国的项目,应供应商要求,需要将每天的交易生成pdf格式的报表上传到供应商的服务器,特此记录实现方法.废话不多说,直接上代码: THSarabunNew.ttf该文件是泰国字体自行网上 ...
- opencv3 使用glob遍历并修改文件名
1.函数说明 string::find()函数:是一个字符或字符串查找函数,该函数有唯一的返回类型,即string::size_type,即一个无符号整形类型,可能是整数也可能是长整数.如果查找成功, ...
- CSS3如何实现圆圈转圈,附demo
如图,如何实现圆圈转圈? 主要还是CSS3动画(只兼容了谷歌,需要兼容其它浏览器,加前缀即可) .move1 { animation: myMove1 5s ease-in infinite alte ...