zoukankan      html  css  js  c++  java
  • [USACO12MAR]花盆Flowerpot (单调队列,二分答案)

    题目链接


    Solution

    转化一下,就是个单调队列.
    可以发现就是一段区间 ([L,R]) 使得其高度的极差不小于 (d) ,同时满足 (R-L) 最小.
    然后可以考虑二分然后再 (O(n)) 判断, 时间复杂度 (O(nlogn)) .

    Code

    #include<bits/stdc++.h>
    #define ll long long
    #define inf 0x3f3f3f3f
    using namespace std;
    const int maxn=1000008;
    
    ll n,d;
    ll ans;
    struct point{
        ll x,y;
    }a[maxn];
    bool jud(int len)
    {
        int qmax[maxn],qmin[maxn];
        int h1,h2,t1,t2;
        h1=h2=1,t1=t2=0;
        qmax[0]=qmin[0]=0;
        for(int i=1;i<=n;++i)
        {
            while(h1<=t1 && a[i].y>a[qmax[t1]].y)--t1;
            qmax[++t1]=i;
            while(h2<=t2 && a[i].y< a[qmin[t2]].y)--t2;
            qmin[++t2]=i;
            while(h1<=t1 && a[i].x-a[qmax[h1]].x>len)++h1;
            while(h2<=t2 && a[i].x-a[qmin[h2]].x>len)++h2;
            if(a[qmax[h1]].y-a[qmin[h2]].y>=d) return 1;
        }
        return 0;
    }
    
    bool cmp(point s,point t)
    {return s.x<t.x;}
    
    int main()
    {
        scanf("%lld%lld",&n,&d);
        for(int i=1;i<=n;i++)
            scanf("%lld%lld",&a[i].x,&a[i].y);
        sort(a+1,a+n+1,cmp);
        int l=1,r=maxn;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(jud(mid)){ans=mid;r=mid-1;}
            else l=mid+1;
        }
        if(ans)
        printf("%lld
    ",ans);
        else puts("-1
    ");
        return 0;
    }
    
  • 相关阅读:
    Javascript高性能编程-提高Dom访问速度
    获取在线人数
    js倒计时
    支付宝支付
    微信扫码支付
    多条sql语句实现事物处理
    防止页面重复刷新
    bootstrapTable.js 使用
    org_chart.js 使用方法
    js上传图片及时显示
  • 原文地址:https://www.cnblogs.com/Kv-Stalin/p/9705699.html
Copyright © 2011-2022 走看看