传送门
偶然看见的一道题,震惊,我还打过这场,咋没补题???
其实就是给出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);
}