HPU personal training

K - Two Contests

原题链接:https://agc040.contest.atcoder.jp/tasks/agc040_b?lang=en

题目大意:

给一个区间集合,将这些区间分为两个集合,求两个区间中线段交集的最大值。

解题思路:

首先找到这些区间的右端点在最左端的区间p,左端点在最右端的区间q。

  1. 如果p,q在同一个集合中,那么这个集合的最大交集就是p_r - q_l,而另一个只放一个最大的区间,得到ans1。
  2. 如果不在同一个区间,想一下集合区间的特征,含有p的集合S中,区间的右端点都大于p的右端点,那么他们的最大交集就是p_R - min_L{ L属于集合S} + 1,含有q的集合T中,区间的左端点都小于q的左端点,那么他们的最大交集就是min_R{R属于集合T} - q_l + 1.可以知道如果直接从所有集合中找最合适期间,那么找到的这个区间可能既在S集合中又在T集合中,所以不能这样找。因此要用到后缀最小值。首先对于每一个区间存储R-mxl+1和mnR-L+1两个数据。然后按其中一个数据对数组排列大小,(要从大的开始,因为大的在一个集合中,所有比他小的都在另一个集合中,然后从大到小找两个集合中的最小交集,这样就可以用后缀最小值了。) 

代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 1e5 + 7;
 4 struct aa{
 5     int first,second;
 6 }P; 
 7 aa arr[N];//记录区间 
 8 int minnore[N]; 
 9 aa S[N];
10 
11 bool cmp1(aa a, aa b){
12     return a.first > b.first;
13 }
14 
15 int main(){
16     int q, L, R, mxL = 0, mnR = 1e9 + 7, RR, LL;
17     int flag1 = 0, flag2 = 0, maxlen = 0;
18     scanf("%d", &q);
19     for(int i = 0; i < q; i ++ ){
20         scanf("%d%d", &L, &R);
21         arr[i].first = L;
22         arr[i].second = R;
23         if(L > mxL){
24             mxL = L;
25             RR = R;
26             flag1 = i;
27         }
28         if(R < mnR){
29             mnR = R;
30             LL = L;
31             flag2 = i;
32         } 
33         maxlen = max(maxlen, R - L + 1);
34     }
35     int ans1 = maxlen;
36     if(mnR >= mxL)    ans1 += mnR - mxL + 1;
37     if(flag1 == flag2){
38         cout << ans1 << endl;
39         return 0;
40     }
41     for(int i = 0; i < q; i ++ ){
42         S[i].first = max(arr[i].second - mxL + 1, 0);
43         S[i].second = max(mnR - arr[i].first + 1, 0);
44     }
45     sort(S, S + q, cmp1);
46     minnore[q-1] = S[q - 1].second;
47     for(int i = q - 2; i >= 0; i --){
48         minnore[i] = min(minnore[i + 1], S[i].second);
49     }
50     int ans2 = 0;
51     for(int i = 0; i < q; i ++ ){
52         ans2 = max(ans2, S[i].first + minnore[i+1]);
53     }
54     cout << max(ans2,ans1) <<endl;
55     return 0;
56 } 

 

 

原文地址:https://www.cnblogs.com/meanttobe/p/11892674.html