zoukankan      html  css  js  c++  java
  • 小小粉丝度度熊 二分答案 + two pointer

    http://acm.hdu.edu.cn/showproblem.php?pid=6119

    发现自己的two pointer能力超弱。

    这题是合并时间后,二分答案。

    可以知道对于每个时间区间,合法的答案肯定是从其开始时间,向左扩展

    或者从其结束时间,向右扩展。

    复杂度O(2n log val)

    细节有点恶心

    #include <bits/stdc++.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    const int maxn = 100000 + 20;
    struct Node {
        int be, en;
        bool operator < (const struct Node & rhs) const {
            if (be != rhs.be) return be < rhs.be;
            else return en < rhs.en;
        }
    }node[maxn];
    int m, n;
    LL sum[maxn];
    bool check(LL val) {
        int p1 = 1, p2 = 1;
        while (p1 <= n) {
            while (p2 <= n && node[p2].en - node[p1].be + 1 < val) {
                p2++;
            }
            if (p2 == n + 1) {
                LL cut = sum[n] - sum[p1];
                cut += node[p1].be + val - 1 - node[n].en;
                if (cut <= m) return true;
                p1++;
                continue;
            }
    //        if (node[p2].en - node[p1].be + 1 < val) break;
            if (node[p2].be - node[p1].be + 1 > val) {
                if (sum[p2 - 1] - sum[p1] + node[p1].be + val - 1 - node[p2 - 1].en <= m) return true;
            } else {
                if (sum[p2] - sum[p1] <= m) return true;
            }
            p1++;
        }
        p1 = p2 = 1;
        while (p2 <= n && node[p2].en < val) p2++;
        while (p2 <= n) {
            while (p1 <= n && node[p2].en - node[p1].en + 1 > val) {
                p1++;
            }
            if (node[p2].en - node[p1].be + 1 >= val) {
                if (sum[p2] - sum[p1] <= m) return true;
            } else {
                LL cut = sum[p2] - sum[p1];
                LL to = node[p2].en - val + 1;
                cut += node[p1].be - to;
                if (cut <= m) return true;
            }
            p2++;
        }
        return false;
    }
    void work() {
        for (int i = 1; i <= n; ++i) {
            scanf("%d%d", &node[i].be, &node[i].en);
        }
        sort(node + 1, node + 1 + n);
        int len = 1;
        for (int i = 2; i <= n; ++i) {
            if (node[len].en >= node[i].be) node[len].en = max(node[len].en, node[i].en);
            else {
                node[++len] = node[i];
            }
        }
        n = len;
        for (int i = 2; i <= n; ++i) {
            sum[i] = sum[i - 1] + node[i].be - node[i - 1].en - 1;
        }
        LL be = 0, en = 1e15;
        for (int i = 1; i <= n; ++i) {
            be = max(be, 1LL * node[i].en - node[i].be + 1);
        }
        while (be <= en) {
            LL mid = (be + en) >> 1;
            if (check(mid)) be = mid + 1;
            else en = mid - 1;
        }
        cout << en << endl;
    }
    
    int main() {
    #ifdef local
        freopen("data.txt", "r", stdin);
    //    freopen("data.txt", "w", stdout);
    #endif
        while (scanf("%d%d", &n, &m) > 0) work();
        return 0;
    }
    View Code
  • 相关阅读:
    Codeforces-799C-Fountains(分类讨论+线段树)
    HDU-3486-Interviewe(二分+RMQ)
    小技巧---查doc文档的index.html怎么用的和chm一样
    chm文件右边部分查看不了
    最长公共临时文档7
    拓展欧几里得临时文档5
    关于myeclipse代码提示的一些问题
    mysql--乱码
    三分--Football Goal(面积最大)
    printf的一个常用技巧
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/7360432.html
Copyright © 2011-2022 走看看