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 }

 

posted @ 2018-04-08 17:15  天之道,利而不害  阅读(181)  评论(0编辑  收藏  举报