zoukankan      html  css  js  c++  java
  • P2698 [USACO12MAR]花盆Flowerpot

    想到了一个二分 + 线段树检验的方法. 就是二分长度, 然后用线段树记录最小&最大值, 暴力扫一遍查询.
    但是这样复杂度貌似是 (O(N(logN)^2)) 的, 太菜了.

    按照以往的经验, 凡是想到这样的思路多半可以用单调队列优化, 一个队列维护最小值, 一个维护最大值就ok.

    #include <cstdio>
    #include <cstring>
    #include <cassert>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    typedef pair<int, int> P;
    const int MAXN = 100000 + 10;
    const int MAXD = 1000000 + 10;
    inline int read(){
        char ch = getchar(); int x = 0;
        while(!isdigit(ch)) ch = getchar();
        while(isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
        return x;
    }
    
    int N, D;
    P a[MAXN], lim[MAXD];
    int qmin[MAXD], qmax[MAXD];
    inline bool check(int x, int len) {
        int lmin = 1, lmax = 1, rmin = 0, rmax = 0;
        for(int i = 1; i <= len; i++) {
            while(lmin <= rmin && (i - qmin[lmin]) > x) ++lmin;
            while(lmax <= rmax && (i - qmax[lmax]) > x) ++lmax;
    
            while(lmin <= rmin && lim[qmin[rmin]].first > lim[i].first) --rmin;
            while(lmax <= rmax && lim[qmax[rmax]].second < lim[i].second) --rmax;
            qmin[++rmin] = i, qmax[++rmax] = i;
    
            if(lim[qmax[lmax]].second - lim[qmin[lmin]].first >= D) return true;
        }
        return false;
    }
    
    int main(){
    //  freopen("p2698.in", "r", stdin);
        cin>>N>>D;
        for(int i = 1; i <= N; i++) 
            a[i].first = read(), a[i].second = read();
        
        int len = 0;
        for(int i = 1; i <= N; i++) len = max(len, a[i].first);
        for(int i = 1; i <= len; i++) lim[i] = P((1 << 30), 0);
        for(int i = 1; i <= N; i++)
            lim[a[i].first].first = min(lim[a[i].first].first, a[i].second),
            lim[a[i].first].second = max(lim[a[i].first].second, a[i].second);
    
        int l = 0, r = len + 1;
        while(l < r) {
            int mid = (l + r) >> 1;
            if(check(mid, len)) r = mid;
            else l = mid + 1;
        }
        if(l == len + 1) puts("-1");
        else printf("%d
    ", l);
        return 0;
    }
    
    
  • 相关阅读:
    使用Sed抽取MySQL安装文档的目录及行号
    [MySQL]关于Com_状态
    [译]理解对象存储如何工作
    [译]OpenStack Object Storage Monitoring
    通过设置swift中container的ACL提供匿名访问及用户授权读取服务
    使用swift命令遭遇503错误
    swift-get-nodes简单使用
    修改虚拟硬盘的大小
    php-fpm重启
    Windows学习"Network Analysis in Python"
  • 原文地址:https://www.cnblogs.com/wsmrxc/p/9814481.html
Copyright © 2011-2022 走看看