zoukankan      html  css  js  c++  java
  • 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
    ", ans);
    91     }
    92     return 0;
    93 }
  • 相关阅读:
    新工作 Day24 周六
    新工作 Day23 周五
    新工作 Day22 周四
    新工作 Day21 周三
    新工作 Day20 周二
    新工作 Day19 周一
    新工作 Day18 周日
    新工作 Day17 周六
    java线程池 多线程搜索文件包含关键字所在的文件路径
    java实现搜索文件夹中所有文件包含的关键字的文件路径(递归搜索)
  • 原文地址:https://www.cnblogs.com/zgglj-com/p/8746147.html
Copyright © 2011-2022 走看看