# 会议中心

1) 这条线段没有接触到任何一个被覆盖的点。

2) 那么这条线段一定落在一个可行区间[L', R']中。设MT(A, B)表示区间[A, B]最多能放几条线段，就必须满足MT(L', L - 1) + MT(R + 1, R') + 1 = MT(L', R')。

1. #include <cstdio>
2. #include <cstring>
3. #include <cstdlib>
4. #include <vector>
5. #include <set>
6. #include <algorithm>
7. using namespace std;
8.
9. const int mi = 19931117;
10. int lsh[500020], lsht[500020], lshmr;
11. void initialize (void)
12. {
13. sort(lsh, lsh + lshmr);
14. int cnt = 0;
15. for (int i = 0; i < lshmr; i++)
16. {
17. if (i == 0 || lsh[i] != lsh[i - 1])
18. lsht[cnt++] = lsh[i];
19. } lshmr = cnt;
20. }
21. inline int place (int a)
22. {
23. int st = 0, ed = lshmr, mid;
24. while (ed - st > 1)
25. {
26. mid = (st + ed) >> 1;
27. if (lsht[mid] > a) ed = mid;
28. else st = mid;
29. } return st + 1;
30. }
31. pair<int, int> require[250010];
32. pair<int, int> rs[250010], trs[250010]; int trmr;
33. bool comp (const pair<int, int>& a, const pair<int, int>& b)
34. {
35. if (a.first != b.first) return a.first < b.first;
36. else return a.second > b.second;
37. }
38.
39. int jump[20][500010], maxj;
40. void jump_st (void)
41. {
42. int p = 0; jump[0][lshmr + 1] = mi;
43. for (int i = lshmr; i >= 1; i--)
44. {
45. if (p < trmr && i == trs[p].first) jump[0][i] = trs[p++].second + 1;
46. else jump[0][i] = jump[0][i + 1];
47. }
48. bool valid;
49. for (int i = 1; ; i++)
50. {
51. valid = false;
52. jump[i][lshmr + 1] = mi;
53. for (int k = 1; k <= lshmr; k++)
54. {
55. if (jump[i - 1][k] == mi) jump[i][k] = mi;
56. else jump[i][k] = jump[i - 1][jump[i - 1][k]];
57. if (jump[i][k] < mi) valid = true;
58. }
59. if (valid == false) { maxj = i - 1; break; }
60. }
61. }
62. int max_time (int s, int e)
63. {
64. if (s >= e) return 0;
65. int ts = s, ans = 0; ++e;
66. for (int j = maxj; j >= 0 && ts < e; j--)
67. if (jump[j][ts] <= e) ts = jump[j][ts], ans += (1 << j);
68. return ans;
69. }
70. set<pair<int, int> > query;
71. typedef set<pair<int, int> >::iterator ptr; int ans;
72. bool judge (int i)
73. {
74. int l = require[i].first, r = require[i].second;
75. ptr t1, t2;
76. t1 = query.lower_bound(make_pair(l, mi));
77. if (t1 == query.begin()) return false; else --t1;
78. if (t1->second < l) return false;
79. t2 = --query.lower_bound(make_pair(r, mi));
80. if (t1 != t2) return false;
81. if (t1->second < r) return false;
82. int ll = t1->first, rr = t1->second;
83. int tans = max_time(ll, l - 1) + max_time(r + 1, rr) + 1;
84. int sans = max_time(ll, rr);
85. if (tans < sans) return false;
86. else
87. {
88. query.erase(t1);
89. if (ll <= l - 1) query.insert(make_pair(ll, l - 1));
90. if (r + 1 <= rr) query.insert(make_pair(r + 1, rr));
91. return true;
92. }
93. }
94. int main ()
95. {
96. int n, ans; scanf("%d", &n), lshmr = 0;
97. for (int i = 0; i < n; i++)
98. {
99. scanf("%d %d", &require[i].first, &require[i].second);
100. lsh[lshmr++] = require[i].first;
101. lsh[lshmr++] = require[i].second;
102. }
103. initialize();
104. for (int i = 0; i < n; i++)
105. {
106. int l = place(require[i].first), r = place(require[i].second);
107. require[i].first = l, require[i].second = r;
108. rs[i] = make_pair(l, r);
109. }
110. sort(rs, rs + n, comp), trmr = 0; int p;
111. for (int i = n - 1; i >= 0; i--)
112. {
113. if (i == n - 1 || rs[i].second < rs[p].second)
114. trs[trmr++] = rs[i], p = i;
115. }
116. jump_st();
117. query.insert(make_pair(1, lshmr));
118. printf("%d\n", ans = max_time(1, lshmr));
119. for (int i = 0; i < n; i++)
120. if (judge(i)) printf("%d ", i + 1);
121. printf("\n");
122. return 0;
123. }
124.

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客