原题链接: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
于是我们离散化区间端点,使其被另一个数代替,但有对其使用差分有着相同的效果
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 }
标签:int,mid,加减,差分,times,端点,区间 From: https://www.cnblogs.com/cilinmengye/p/16794245.html