Round B APAC Test 2017 Problem C. Watson and Intervals
来源:互联网 发布:centos和ubuntu哪个好 编辑:程序博客网 时间:2024/05/18 03:11
Problem C. Watson and Intervals
Sherlock and Watson have mastered the intricacies of the language C++ in their programming course, so they have moved on to algorithmic problems. In today's class, the tutor introduced the problem of merging one-dimensional intervals. N intervals are given, and the i
th interval is defined by the inclusive endpoints [Li, Ri], where Li ≤ Ri.
The tutor defined the covered area of a set of intervals as the number of integers appearing in at least one of the intervals. (Formally, an integer p contributes to the covered area if there is some j such that Lj ≤ p
≤ Rj.)
Now, Watson always likes to challenge Sherlock. He has asked Sherlock to remove exactly one interval such that the covered area of the remaining intervals is minimized. Help Sherlock find this minimum possible covered area, after removing exactly one of theN intervals.
Input
Each test case consists of one line with eight integers N, L1, R1, A, B, C1, C2, and M. N is the number of intervals, and the other seven values are parameters that you should use to generate the other intervals, as follows:
First define x1
= L1 and y1
= R1. Then, use the recurrences below to generate xi, yi
for i
= 2 to N:
xi
= ( A*xi-1
+ B*yi-1
+ C1 ) modulo M.yi
= ( A*yi-1
+ B*xi-1
+ C2 ) modulo M.
min(xi, yi)
and Ri = max(xi, yi)
, for all i
= 2 to N.Output
For each test case, output one line containing Case #x: y
, where x
is the test case number (starting from 1) and y
is the minimum possible covered area of all of the intervals remaining after removing exactly one interval.
Limits
1 ≤ T ≤ 50.
0 ≤ L1 ≤ R1 ≤ 109.
0 ≤ A ≤ 109.
0 ≤ B ≤ 109.
0 ≤ C1 ≤ 109.
0 ≤ C2 ≤ 109.
1 ≤ M ≤ 109.
Small dataset
1 ≤ N ≤ 1000.
Large dataset
1 ≤ N ≤ 5 * 105(500000).
Sample
In case 1, using the generation method, the set of intervals generated are: {[1, 1]}. Removing the only interval, the covered area is 0.In case 2, using the generation method, the set of intervals generated are: {[2, 5], [3, 5], [4, 7]}. Removing the first, second or third interval would cause the covered area of remaining intervals to be 5, 6 and 4, respectively.
In case 3, using the generation method, the set of intervals generated are: {[3, 4], [1, 9], [0, 8], [2, 4]}. Removing the first, second, third or fourth interval would cause the covered area of remaining intervals to be 10, 9, 9 and 10, respectively.
Solution
#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <vector>#include <stack>#include <list>#include <map>#include <set>#include <iterator>#include <unordered_set>#include <unordered_map>#include <algorithm>using namespace std;typedef long long ll;struct Point{ int id; int pos; int type; Point() {} Point(int id, int pos, int type): id(id), pos(pos), type(type) {} bool operator <(const Point& p) const { if (pos == p.pos) return type < p.type; else return pos < p.pos; }};const int MAXN = 5e5;Point points[2*MAXN];int singleIntervals[MAXN];int main(int argc, char* argv[]){#ifndef TEST if (argc != 2) { cout << "Invalid input" << endl; return 1; } string input = argv[1]; string output = input.substr(0, input.length() - 2) + "out"; freopen(input.c_str(), "r", stdin); freopen(output.c_str(), "w", stdout);#endif int T; int N, L1, R1, A, B, C1, C2, M; cin >> T; for (int i = 1; i <= T; i++) { cin >> N >> L1 >> R1 >> A >> B >> C1 >> C2 >> M; points[0] = Point(0, L1, 0); points[1] = Point(0, R1, 1); for (int j = 1; j < N; j++) { int Xi, Yi; Xi=((ll)A*L1+(ll)B*R1+C1)%M; Yi=((ll)A*R1+(ll)B*L1+C2)%M; points[2*j] = Point(j, min(Xi, Yi), 0); points[2*j+1] = Point(j, max(Xi, Yi) + 1, 1); L1 = Xi; R1 = Yi; } sort(points, points + 2 * N); int totalLen = 0, maxSingleLen = 0; int cnt = 0, start = 0, lastEnd = 0; memset(singleIntervals, 0, sizeof(singleIntervals)); set<int> coveredIds; for (int j = 0; j < 2 * N; j++) { if (coveredIds.size() == 1) { int id = *(coveredIds.begin()); singleIntervals[id] += points[j].pos - lastEnd; maxSingleLen = max(maxSingleLen, singleIntervals[id]); } if (points[j].type == 0) { coveredIds.insert(points[j].id); if (cnt == 0) lastEnd = start = points[j].pos; cnt++; } else { lastEnd = points[j].pos; coveredIds.erase(points[j].id); cnt--; if (cnt == 0) totalLen += points[j].pos - start; } } cout << "Case #" << i << ": " << totalLen - maxSingleLen << endl; } fclose(stdin); fclose(stdout); return 0;}
Note
将一条线段,拆分为2个点,左端点表示进入,右端点表示离开,在数据结构中用type表示(0表示进入,1表示离开)。然后将这些点按照规则排序(令points表示排序后的点数组),时间复杂度为O(NlogN)。
注意:
1. 对于线段、时间片段相关的题目,经常用这种方法做预处理。
2. 在我的实现中,使用了一个小的trick,两个端点使用了左闭又开的形式,即 Ri' = Ri + 1。这样做是为了便于对覆盖一个点的线段计数(令cnt表示覆盖某一个点的线段的总数)。
先来考虑如何统计所有线段覆盖的总长度?
在处理完线段重合后,当cnt为1的时候,只可能是重合线段的左端点或右端点,我们只需从左到右遍历points,找出这些点,就可以计算出总长度了,时间复杂度为O(N)。
线段之间有重合,所以本题难点在于计算出每一条线段独占的长度。换个角度考虑,就是找出只被覆盖1次的点,分别属于哪条线段。我们只要求出独占长度最长的线段,就可以得到问题的解。
同样的,在处理完线段重合后,每一个重合线段,都可以用一个set来表示这个重合线段由哪些线段组成。进一步思考,每一个重合线段上的点,也可以用一个set来表示这个点由哪些线段覆盖,set的size为1的点,即为被独占的点,此时set中唯一元素即为这个点属于的线段。这样,我们就可以计算出每一个线段的独占长度,时间复杂度为O(N)。
Reference
https://code.google.com/codejam/contest/5254487/dashboard#s=p2
- Round B APAC Test 2017 Problem C. Watson and Intervals
- Problem C. Watson and Intervals Google APAC 2017 University Test Round B
- Round B APAC Test 2017 Problem B. Sherlock and Watson Gym Secrets
- Problem B. Sherlock and Watson Gym Secrets Google APAC 2017 University Test Round B
- Round B APAC Test 2017 Problem A. Sherlock and Parentheses
- Round C APAC Test 2017 Problem B. Safe Squares (C++)
- Round C APAC Test 2017 Problem B. Monster Path
- Google APAC test 2015 Round B Problem C - Card Game
- Problem B. gFiles Google APAC 2016 University Test Round C
- Problem C. gNumbers Google APAC 2016 University Test Round B
- Round B APAC Test 2017 Problem D. Sherlock and Permutation Sorting
- Problem A. Sherlock and Parentheses Google APAC 2017 University Test Round B
- Practice Round APAC test 2017--Problem B. Robot Rock Band
- Round E APAC Test 2017 Problem B. Beautiful Numbers
- Problem B. Rain Google APAC 2017 University Test Round A
- Round A APAC Test 2017 Problem B.Rain
- Problem B. Safe Squares Google APAC 2017 University Test Round C
- Round C APAC Test 2017 Problem C. Evaluation
- 记录ccui.listView打开界面不置顶的问题
- UML中的事物
- maven 手工添加oracle 驱动jar 到本地仓库
- 基于阿里云的maven配置
- 一起来搭建像Qt一样的win32图形框架(2)
- Round B APAC Test 2017 Problem C. Watson and Intervals
- Leetcode 100 Same Tree
- UML准备
- hdu 5884 Sort(二分+哈夫曼树(队列))
- 关闭layer组件当前的弹层的方法
- http://blog.csdn.net/CaspianSea/article/details/43014525
- 【C++】【PAT】1050螺旋矩阵
- 环形缓冲区的实现原理(ring buffer)
- 农场一头小母牛,每年生头小母牛,母牛5岁产母牛,20年上多少牛?--java面向对象方式实现