poj 1201 Intervals

                                                                                                                                                                  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.

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\n",res);
    return 0;
}

 

posted on 2017-06-12 20:23  ZefengYao  阅读(140)  评论(0编辑  收藏  举报

导航