第一行输入整数
。
随后
行,每行两个整数
(
) 描述一条线段。
输出满足条件的方案数对
取模的结果。
5 4 4 5 1 5 3 5 1 4
3
import java.util.*;
// m较小, 状态压缩枚举所有可能 + 差分检查
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt(), m = in.nextInt();
int[][] line = new int[m][2];
for (int i = 0; i < m; i++) {
line[i][0] = in.nextInt();
line[i][1] = in.nextInt();
}
int res = 0;
for (int i = 1; i < (1 << m); i++) {
TreeMap<Integer, Integer> map = new TreeMap<>();
for (int x = i, k = 0; x > 0; x >>= 1, k++) {
if ((x & 1) == 1) { // 选:差分 [line[k][0],line[k][1]]区间都+1
map.merge(line[k][0], 1, Integer::sum);
map.merge(line[k][1] + 1, -1, Integer::sum);
}
}
if (check(map, n)) {
res++;
}
}
System.out.print(res);
}
// 检查[1,n]每个点能否被覆盖至少2次
private static boolean check(TreeMap<Integer, Integer> map, int n) {
if (map.firstKey() != 1 || map.lastKey() != n + 1)// 未覆盖[1,n]
return false;
int sum = 0;
for (Map.Entry<Integer, Integer> e : map.entrySet()) {
sum += e.getValue();
if (e.getKey() <= n && sum < 2) // 中间次数 < 2
return false;
}
return true;
}
}