Intervals
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 26973 | Accepted: 10363 |
Description
You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn.
Write a program that:
reads the number of intervals, their end points and integers c1, ..., cn from the standard input,
computes the minimal size of a set Z of integers which has at least ci common elements with interval [ai, bi], for each i=1,2,...,n,
writes the answer to the standard output.
Write a program that:
reads the number of intervals, their end points and integers c1, ..., cn from the standard input,
computes the minimal size of a set Z of integers which has at least ci common elements with interval [ai, bi], for each i=1,2,...,n,
writes the answer to the standard output.
Input
The first line of the input contains an integer n (1
<= n <= 50000) -- the number of intervals. The following n lines describe
the intervals. The (i+1)-th line of the input contains three integers ai, bi and
ci separated by single spaces and such that 0 <= ai <= bi <= 50000 and
1 <= ci <= bi - ai+1.
Output
The output contains exactly one integer equal to the
minimal size of set Z sharing at least ci elements with interval [ai, bi], for
each i=1,2,...,n.
Sample Input
5 3 7 3 8 10 3 6 8 1 1 3 1 10 11 1
Sample Output
6
题意:给定n个区间,每个区间[ai,bi],要求从n个区间中选出尽量少的元素组成集合Z,使得集合Z与每一个区间至少有ci个数是相同的,求集合Z的大小。
思路:贪心,每个区间按照右端点的从小到大排序,从尾部最小的区间开始,尽量挑选尾部的元素,这样就有更大的可能和后面的区间发生关系,从而使得集合尽量的小,可以用BIT来存储,更快的得到某个元素之前的元素使用情况。
AC代码:
#define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<algorithm> #include<vector> using namespace std; const int N_MAX = 50000 + 5; int res = 0; int vis[N_MAX]; struct interval { int l,r,num; bool operator <(const interval&b) const { return this->r < b.r;//以区间的右端点来排序 } }inter[N_MAX]; struct BinaryIndexedTree { int bit[N_MAX], n; void init(int N) { memset(bit,0,sizeof(bit)); n = N; } int sum(int i) { int s = 0; while (i>0) { s += bit[i]; i -= i&-i; } return s; } void add(int i,int x) { while (i<=n) { bit[i] += x; i += i&-i; } } }; BinaryIndexedTree BIT; int main() { int n; scanf("%d",&n); memset(vis, 0, sizeof(vis)); for (int i = 0; i < n;i++) { scanf("%d%d%d",&inter[i].l,&inter[i].r,&inter[i].num); } sort(inter, inter + n); BIT.init(inter[n-1].r); int num = inter[0].num; for (int i = 0; i < n;i++) { int right = inter[i].r; while (num) { if (!vis[right]) {//该位置上的数还没使用过 BIT.add(right, 1); num--; vis[right] = true; res++; } right--; } //接下来改变num的值 if (i + 1 < n) { num = inter[i + 1].num - (BIT.sum(inter[i + 1].r) - BIT.sum((inter[i + 1].l)-1));//下一个区间还需要选多少数字 if (num < 0)num = 0;// } } printf("%d ",res); return 0; }