Wannafly挑战赛13-E
题解:~~~~不太好想,用线段树记录区间内的最大值和最小值,什么是最大值?当两条线段相交但不包含的时候,len=l2+r2-(l1+r1),所以最大值是指区间内所有线段左右端点之和
的最大值。同理,当两条线段相交但是包含得时候,len=r1-l1-(r2-l2),所以最小值是指区间内所有线段长度的最小值。对于不想交的线段在查询的时候就会丢掉。
感受:想到分类讨论就豁然开朗。还有一个小技巧就是针对每条线段找查询区间会用到二分。还有其他的做法不会。。。
1 #pragma warning(disable:4996) 2 #include<bitset> 3 #include<string> 4 #include<cstdio> 5 #include<cstring> 6 #include<iostream> 7 #include<algorithm> 8 #define lson l,mid,root<<1 9 #define rson mid+1,r,root<<1|1 10 using namespace std; 11 typedef long long ll; 12 13 const int maxn = 200005; 14 const int INF = 1e9 + 7; 15 16 int n; 17 int Max[maxn << 2], Min[maxn << 2]; 18 19 struct node { 20 int l, r; 21 friend bool operator<(const node& a, const node& b) { 22 return a.l < b.l; 23 } 24 }s[maxn]; 25 26 void Pushup(int root) { 27 Max[root] = max(Max[root << 1], Max[root << 1 | 1]); 28 Min[root] = min(Min[root << 1], Min[root << 1 | 1]); 29 } 30 31 void Build(int l, int r, int root) { 32 if (l == r) { 33 Max[root] = s[l].l + s[l].r; 34 Min[root] = s[l].r - s[l].l; 35 return; 36 } 37 int mid = (l + r) >> 1; 38 Build(lson); 39 Build(rson); 40 Pushup(root); 41 } 42 43 44 int Query1(int L, int R, int l, int r, int root) { 45 46 if (L > r || R < l) return 0; 47 if (L <= l && r <= R) return Max[root]; 48 49 int mid = (l + r) >> 1; 50 int ans = 0; 51 ans = max(ans, Query1(L, R, lson)); 52 ans = max(ans, Query1(L, R, rson)); 53 return ans; 54 } 55 56 int Query2(int L, int R, int l, int r, int root) { 57 58 if (L > r || R < l) return INF; 59 if (L <= l && r <= R) return Min[root]; 60 61 int mid = (l + r) >> 1; 62 int ans = INF; 63 ans = min(ans, Query2(L, R, lson)); 64 ans = min(ans, Query2(L, R, rson)); 65 return ans; 66 } 67 68 int main() 69 { 70 while (scanf("%d", &n) != EOF) { 71 for (int i = 1; i <= n; i++) scanf("%d%d", &s[i].l, &s[i].r); 72 sort(s + 1, s + n + 1); 73 Build(1, n, 1); 74 node tmp; 75 tmp.r = 0; 76 int ans = 0; 77 for (int i = 1; i <= n; i++) { 78 79 tmp.l = s[i].l; 80 int l = lower_bound(s + 1, s + n + 1, tmp) - s; 81 tmp.l = s[i].r; 82 int r = upper_bound(s + 1, s + n + 1, tmp) - s - 1; 83 84 if (l > r) continue; 85 int tmp1 = Query1(l, r, 1, n, 1); 86 int tmp2 = Query2(l, r, 1, n, 1); 87 ans = max(ans, tmp1 - (s[i].l + s[i].r)); 88 ans = max(ans, (s[i].r - s[i].l) - tmp2); 89 } 90 printf("%d\n", ans); 91 } 92 return 0; 93 }