运用离散化缩小不必要的范围+差分:只通过对两个区间的端点进行加减操作即可使这段区间上的元素得到加减
原题链接:https://codeforces.com/gym/403650/problem/C
题目的原意是:给定n个区间,求1-1e9这个数轴上,对于每一个数点,在给定区间上出现过的最大值
一个最朴素的想法是:每给出一段区间,我们就让这个区间上代表的数num,count[num]++
然后排个序,找到最大的count[x];
但是会超时,而且num为1—1e9,没有那个数组能开这么大
差分:https://www.cnblogs.com/cilinmengye/p/16325069.html
离散化常用的去重方法:
前提是:数组是用vector来装
于是我们离散化区间端点,使其被另一个数代替,但有对其使用差分有着相同的效果
1 #include <iostream>
2 #include <algorithm>
3 #include <cstring>
4 using namespace std;
5 typedef pair<int, int> PII;
6 const int N = 2e5 + 5;
7 int n;
8 int pre[N], times[N];
9 int index1 = 0, pos = 0;
10 bool rule(int a, int b)
11 {
12 return a < b;
13 }
14 PII rounds[N];
15 int chafen[N];
16 int he[N];
17 void dre()
18 {
19 int lastNum = pre[1];
20 for (int i = 2; i <= index1; i++)
21 {
22 if (lastNum != pre[i])
23 {
24 times[++pos] = lastNum;
25 lastNum = pre[i];
26 }
27 }
28 times[++pos] = lastNum;
29 }
30 int find(int x)
31 {
32 int l = 1, r = pos, ans;
33 while (l <= r)
34 {
35 int mid = (l + r) >> 1;
36 if (times[mid] < x)
37 l = mid + 1;
38 else if (times[mid] > x)
39 r = mid - 1;
40 else if (times[mid] == x)
41 {
42 ans = mid;
43 break;
44 }
45 }
46 return ans;
47 }
48 main()
49 {
50 cin >> n;
51 for (int i = 1; i <= n; i++)
52 {
53 int a, b;
54 scanf("%d%d", &a, &b);
55 rounds[i] = {a, b};
56 pre[++index1] = a;
57 pre[++index1] = b;
58 }
59 sort(pre + 1, pre + index1 + 1, rule);
60 /* for (int i = 1; i <= index1; i++)
61 cout << pre[i] << " ";
62 cout << endl; */
63 dre();
64 /* for (int i = 1; i <= pos; i++)
65 cout << times[i] << " ";
66 cout << endl; */
67 for (int i = 1; i <= n; i++)
68 {
69 int posl = rounds[i].first;
70 int posr = rounds[i].second;
71 int lisuanl = find(posl);
72 int lisuanr = find(posr);
73 chafen[lisuanl]++;
74 chafen[lisuanr]--;
75 }
76 for (int i = 1; i <= pos; i++)
77 he[i] = he[i - 1] + chafen[i];
78 sort(he + 1, he + pos + 1, [](int a, int b)
79 { return a > b; });
80 cout << he[1];
81 return 0;
82 }