题目链接:https://codeforces.com/contest/1420/problem/D

前言

之前写过这场比赛的题解,不过感觉这一题还可以再单独拿出来好好捋一下思路。

题意

给出 $n$ 个闭区间,问 $k$ 个区间共区间共有多少种情况。

题解一

以区间为单位进行考虑,排序+优先队列。

将所有区间以左端点为第一关键字,右端点为第二关键字从小到大排序,优先队列中存储不小于当前区间左端点的之前区间的右端点,每个区间对答案的贡献即 $C_{(pque.size(),\ k - 1)}$ 。

代码

#include <bits/stdc++.h>
using namespace std;
constexpr int N = 1e6 + 100;
constexpr int MOD = 998244353; int fac[N], inv[N]; int binpow(int a, int b) {
int res = 1;
while (b) {
if (b & 1) res = 1LL * res * a % MOD;
a = 1LL * a * a % MOD;
b >>= 1;
}
return res;
} long long C(int n, int m){
if(m < 0 or m > n) return 0;
return 1LL * fac[n] * inv[m] % MOD * inv[n - m] % MOD;
} void Init(){
fac[0] = 1;
for (int i = 1; i < N; i++) fac[i] = 1LL * fac[i - 1] * i % MOD;
inv[N - 1] = binpow(fac[N - 1], MOD - 2);
for (int i = N - 2; i >= 0; i--) inv[i] = 1LL * inv[i + 1] * (i + 1) % MOD;
} int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); Init(); int n, k;
cin >> n >> k; vector<pair<int, int>> seg(n);
for (auto &[l, r] : seg) cin >> l >> r; sort(seg.begin(), seg.end()); long long ans = 0; priority_queue<int, vector<int>, greater<int>> pque; for (int i = 0; i < n; i++) {
auto [l, r] = seg[i];
while (pque.size() and pque.top() < l) pque.pop();
ans += C(pque.size(), k - 1);
ans %= MOD;
pque.push(r);
} cout << ans << "\n"; return 0;
}

题解二

以点为单位进行考虑,排序+离散化+差分。

记录包含当前点 $i$ 的区间个数 $dif_i$ 和以当前点为左端点的区间个数 $bg_i$,将 $k$ 个区间视为两部分,从之前区间选出的部分和从以当前点为左端点的区间中选出的部分,即 $C_{(dif_i - bg_i,\ k-j)} \times C_{(bg_i,\ j)}$,为了去重 $j$ 的值从 $1$ 取起,值域为 $[1,min(k,\ bg_i)]$,每个点对答案的贡献为 $\sum_{j = 1}^{min(k,\ bg_i)} \limits C_{(dif_i - bg_i,\ k-j)} \times C_{(bg_i,\ j)}$ 。

代码

#include <bits/stdc++.h>
using namespace std;
constexpr int N = 1e6 + 100;
constexpr int MOD = 998244353; int fac[N], inv[N]; int binpow(int a, int b) {
int res = 1;
while (b) {
if (b & 1) res = 1LL * res * a % MOD;
a = 1LL * a * a % MOD;
b >>= 1;
}
return res;
} long long C(int n, int m){
if(m < 0 or m > n) return 0;
return 1LL * fac[n] * inv[m] % MOD * inv[n - m] % MOD;
} void Init(){
fac[0] = 1;
for (int i = 1; i < N; i++) fac[i] = 1LL * fac[i - 1] * i % MOD;
inv[N - 1] = binpow(fac[N - 1], MOD - 2);
for (int i = N - 2; i >= 0; i--) inv[i] = 1LL * inv[i + 1] * (i + 1) % MOD;
} int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); Init(); int n, k;
cin >> n >> k; vector<int> x(n), y(n);
vector<int> disc;
for (int i = 0; i < n; i++) {
cin >> x[i] >> y[i];
disc.push_back(x[i]);
disc.push_back(y[i]);
} sort(disc.begin(), disc.end());
disc.resize(unique(disc.begin(), disc.end()) - disc.begin()); vector<int> dif(disc.size() + 1), bg(disc.size() + 1);
for (int i = 0; i < n; i++) {
int l = lower_bound(disc.begin(), disc.end(), x[i]) - disc.begin();
int r = lower_bound(disc.begin(), disc.end(), y[i]) - disc.begin();
++bg[l];
++dif[l];
--dif[r + 1];
} long long ans = 0;
for (int i = 0; i < int(dif.size()); i++) {
if (i > 0) dif[i] += dif[i - 1];
for (int j = 1; j <= min(k, bg[i]); j++) {
ans += C(dif[i] - bg[i], k - j) * C(bg[i], j);
ans %= MOD;
}
}
cout << ans << "\n"; return 0;
}

Codeforces Round #672 (Div. 2) D. Rescue Nibel!(排序)的更多相关文章

  1. Codeforces Round #672 (Div. 2) D. Rescue Nibel! (思维,组合数)

    题意:给你\(n\)个区间,从这\(n\)区间中选\(k\)个区间出来,要求这\(k\)个区间都要相交.问共有多少种情况. 题解:如果\(k\)个区间都要相交,最左边的区间和最右边的区间必须要相交,即 ...

  2. Codeforces Round #672 (Div. 2) A - C1题解

    [Codeforces Round #672 (Div. 2) A - C1 ] 题目链接# A. Cubes Sorting 思路: " If Wheatley needs more th ...

  3. Codeforces Round #672 (Div. 2)

    比赛链接:https://codeforces.com/contest/1420 A. Cubes Sorting 题意 给出一个大小为 $n$ 的数组 $a$,每次只可以交换相邻的两个元素,最多交换 ...

  4. Codeforces Round #672 (Div. 2) B. Rock and Lever题解(思维+位运算)

    题目链接 题目大意 给你一个长为n(n<=1e5)的数组,让你求有多少对a[i]和a[j] (i!=j)满足a[i]&a[j]>a[i]^a[j] 题目思路 这些有关位运算的题目肯 ...

  5. Codeforces Round #672 (Div. 2) C1. Pokémon Army (easy version) (DP)

    题意:给你一组数\(a\),构造一个它的子序列\(b\),然后再求\(b_1-b2+b3-b4...\),问构造后的结果最大是多少. 题解:线性DP.我们用\(dp1[i]\)来表示在\(i\)位置, ...

  6. Codeforces Round #672 (Div. 2 B. Rock and Lever (位运算)

    题意:给你一组数,求有多少对\((i,j)\),使得\(a_{i}\)&\(a_{j}\ge a_{i}\ xor\ a_{j}\). 题解:对于任意两个数的二进制来说,他们的最高位要么相同要 ...

  7. Codeforces Round #672 (Div. 2) A. Cubes Sorting (思维)

    题意:有一长度为\(n\)的一组数,每次可以交换两个数的位置,问能否在\(\frac{n*(n-1)}{2}-1\)次操作内使得数组非递减. 题解:不难发现,只有当整个数组严格递减的时候,操作次数是\ ...

  8. codeforces Codeforces Round #345 (Div. 1) C. Table Compression 排序+并查集

    C. Table Compression Little Petya is now fond of data compression algorithms. He has already studied ...

  9. Codeforces Round #624 (Div. 3) B. WeirdSort(排序)

    output standard output You are given an array aa of length nn . You are also given a set of distinct ...

随机推荐

  1. Mybatis的CRUD 增删改查

    目录 namespace 命名空间 select insert update delete Mybatis 官网: https://mybatis.org/mybatis-3/zh/getting-s ...

  2. MySQL的CURD 增删改查

    添加 insert 语法: 单条:insert into 表名('字段1', '字段2', ...) values('值1', '值2', ...) 多条:insert into 表名('字段1', ...

  3. Received empty response from Zabbix Agent at [agent]. Assuming that agent dropped connection because of access permission

    Received empty response from Zabbix Agent at [agent]. Assuming that agent dropped connection because ...

  4. xtrabackup_binlog_info

    文件保存了备份结束时刻binlog的名称和位置

  5. 【Linux】find查找空文件夹

    linux下批量删除空文件(大小等于0的文件)的方法 find . -name "*" -type f -size 0c | xargs -n 1 rm -f 就是删除1k大小的文 ...

  6. APP测试之Monkey测试

    一.简介 1.什么是Monkey测试? Monkey testing,也有人叫做搞怪测试.就是用一些稀奇古怪的操作方式去测试被测试系统,以测试系统的稳定性.Monkeytest,一般指这样的测试活动, ...

  7. 未使用绑定变量对share_pool的影响

    oracle SGA中包含数据高速缓冲,重做日志缓冲,以及共享池(share_pool).共享池中包含库高速缓冲(所有的SQL,执行计划等)和数据字典缓冲(对象的定义,权限等). 所以,如果SQL中没 ...

  8. Windows+.Net Framework+svn+IIS在Jenkins上的自动化部署入门

    关于Jenkins的使用及安装,上一篇文章我已经介绍过了,Windows+.NetCore+git+IIS在Jenkins上的自动化部署入门.这篇主要是在jenkins如何安装SVN和MSBuild. ...

  9. kernel升级模式RKS让人振奋

    前几天刚将我的ERP内核从701_rel 升级到721_ext_rel,看到721的说明了讲到,对于这次的更新,支持RKS(Rolling Kernel Switch)了,简单的讲,就是以后对于内核的 ...

  10. [Noip模拟题]Seq

    题目描述 由于hyf长得实在是太帅了,英俊潇洒,风流倜傥,人见人爱,花见花开,车见车载.有一群MM排队看hyf.每个MM都有自己独特的风格,由于hyf有着一颗包容的心,所以,什么风格的MM他都喜欢-- ...