链接:
http://poj.org/problem?id=1201
题意:
给你n个区间,每个区间为[a,b],每个区间取c个数构成一个集合,求集合最小容量
题解:
把区间按b排序,从第一个区间开始取,从后往前取,这样尽可能和后面的区间重复
另外如果我们发现当前区间取得个数已经超过了c,那么只需要让之前区间换就行,而总数是不变的,所以不用更新答案
求当前区间已经取了多少个数用树状数组
代码:
1 #include <map> 2 #include <set> 3 #include <cmath> 4 #include <queue> 5 #include <stack> 6 #include <cstdio> 7 #include <string> 8 #include <vector> 9 #include <cstdlib> 10 #include <cstring> 11 #include <sstream> 12 #include <iostream> 13 #include <algorithm> 14 #include <functional> 15 using namespace std; 16 #define rep(i,a,n) for (int i=a;i<n;i++) 17 #define per(i,a,n) for (int i=n-1;i>=a;i--) 18 #define all(x) (x).begin(),(x).end() 19 #define pb push_back 20 #define mp make_pair 21 #define lson l,m,rt<<1 22 #define rson m+1,r,rt<<1|1 23 typedef long long ll; 24 typedef vector<int> VI; 25 typedef pair<int, int> PII; 26 const ll MOD = 1e9 + 7; 27 const int INF = 0x3f3f3f3f; 28 const int MAXN = 5e4 + 7; 29 // head 30 31 struct sec { 32 int a, b, c; 33 const bool operator<(const sec &t) const { 34 if (b == t.b) return a < t.a; 35 return b < t.b; 36 } 37 }s[MAXN]; 38 39 int n; 40 int bit[MAXN]; 41 int used[MAXN]; 42 43 void add(int i, int x) { 44 while (i <= 5e4) bit[i] += x, i += i&-i; 45 } 46 47 int sum(int i) { 48 int s = 0; 49 while (i) s += bit[i], i -= i&-i; 50 return s; 51 } 52 53 int main() { 54 cin >> n; 55 rep(i, 0, n) scanf("%d%d%d", &s[i].a, &s[i].b, &s[i].c); 56 sort(s, s + n); 57 int ans = 0; 58 rep(i, 0, n) { 59 int picked = sum(s[i].b) - sum(s[i].a - 1); 60 if (picked < s[i].c) { 61 int remain = s[i].c - picked; 62 ans += remain; 63 int tail = s[i].b; 64 while (remain) { 65 if (!used[tail]) { 66 used[tail] = 1; 67 add(tail, 1); 68 remain--; 69 } 70 tail--; 71 } 72 } 73 } 74 cout << ans << endl; 75 return 0; 76 }