cf 1420 D. Rescue Nibel!

传送门
偶然看见的一道题,震惊,我还打过这场,咋没补题???
其实就是给出n个区间,选择k盏灯亮的方式有几种。

一看就知道,这不是差分前缀和+组合数傻逼题吗?哦,区间很大,那不就离散化一下吗???嗯哼,好简单

然后就开始用map去离散化差分前缀和了,判断如果当前区间有值,那么就在选择k盏灯。结果样例过不去???

靠!其实这种题,关于枚举然后再去组合数时,有一个坑点就是选择会重复,

所以一般是枚举你先选择哪个灯,然后再去选择(k-1)盏灯。

因为离散化差分有两种方法,一个是map,一个是排序。
那么就用排序吧。然后枚举每个点,如果当前点是打开的灯,那么选择,然后在选择(k-1)盏灯。求当前有多少灯就直接前缀和就行了

void solve(int kase){
    int n, k;
    scanf("%d%d", &n, &k);
    std::vector<pair<int,int>> v;
    for(int i = 1; i <= n; i++) {
        int l, r; scanf("%d%d", &l, &r);
        v.push_back({l, 1});
        v.push_back({r + 1, -1});
    }
    sort(v.begin(), v.end(),[](pair<int,int> &a, pair<int,int> &b){
        if(a.fi == b.fi) return a.se < b.se;
        return a.fi < b.fi;
    });
    int now = 0;
    ll ans = 0;
    for(int i = 0; i < v.size(); i++) {
        if(v[i].se == 1) {
            ans += Combination::C(now, k - 1);
            ans %= CM;
        }
        now += v[i].se;
    }
    printf("%lld
", ans);
}
原文地址:https://www.cnblogs.com/Emcikem/p/14267062.html