• BZOJ_2369_区间_决策单调性


    BZOJ_2369_区间_决策单调性

    Description

    对于一个区间集合
    {A1,A2……Ak}(K>1,Ai不等于Aj(i不等于J),定义其权值
     
    S=|A1∪A2∪……AK|*|A1∩A2……∩Ak|
    即它们的交区间的长度乘上它们并区间的长度。
    显然,如果这些区间没有交集则权值为0。
    Your Task
    给定你若干互不相等的区间,选出若干区间使其权值最大。

    Input

    第一行n表示区间的个数
    接下来n行每行两个整数l r描述一个区间[l,r]

    Output

     
    在一行中输出最大权值

    Sample Input

    4
    1 6
    4 8
    2 7
    3 5

    Sample Output

    24

    HINT

    样例解释

        选择[1,6]和[2,7]是最优的。

    数据约定

    100%:1<N<=10^6,1<=L<R<=10^6


    首先有结论:肯定有一种最优方案只选了两个,因为选n个不会比只选左右的区间更优。

    于是按左端点排序,然后把区间包含的那种直接统计答案并踢掉。

    现在左右都单调了,可以证明满足决策单调性。

    直接上决策单调性即可。

    注意这道题区间长度为r-l。

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    __attribute__((optimize("-O3")))inline char nc() {
        static char buf[100000],*p1,*p2;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    }
    __attribute__((optimize("-O3")))int rd() {
        int x=0; 
        char s=nc();
        while(s<'0'||s>'9') s=nc();
        while(s>='0'&&s<='9') x=(x<<3)+(x<<1)+s-'0',s=nc();
        return x;
    }
    #define N 1000050
    struct Line {
        int l,r;
        bool operator < (const Line &x) const {
            return l<x.l;
        }
    }a[N];
    struct A {
        int l,r,p;
    }Q[N];
    __attribute__((optimize("-O3")))ll Y(int j,int i) {
        // if(a[j].r<a[i].l) return -1ll<<60;
        return 1ll*(a[j].r-a[i].l)*(a[i].r-a[j].l);
    }
    __attribute__((optimize("-O3")))int find(const A &a,int x) {
        int l=a.l,r=a.r+1;
        while(l<r) {
            int mid=(l+r)>>1;
            if(Y(a.p,mid)>=Y(x,mid)) l=mid+1;
            else r=mid;
        }
        return l;
    }
    ll ans;
    int n;
    __attribute__((optimize("-O3")))int main() {
        n=rd();
        register int i,t=0;
        for(i=1;i<=n;i++) {
            a[i].l=rd();
            a[i].r=rd();
        }
        sort(a+1,a+n+1); a[0].r=-1;
        for(i=1;i<=n;i++) {
            if(a[i].r<=a[t].r) {
                ans=max(ans,1ll*(a[t].r-a[t].l)*(a[i].r-a[i].l));
            }else a[++t]=a[i];
        }
        n=t;
        int l=0,r=0;
        Q[r++]=(A){1,n,1};
        for(i=2;i<=n;i++) {
            if(l<r) Q[l].l++;
            while(l<r&&Q[l].l>Q[l].r) l++;
            if(l<r) ans=max(ans,Y(Q[l].p,i));
            if(l==r||Y(i,n)>Y(Q[r-1].p,n)) {
                while(l<r&&Y(i,Q[r-1].l)>Y(Q[r-1].p,Q[r-1].l)) r--;
                if(l==r) Q[r++]=(A){i,n,i};
                else {
                    int x=find(Q[r-1],i);
                    Q[r-1].r=x-1; Q[r++]=(A){x,n,i};
                }
            }
        }
        printf("%lld
    ",ans);
    }
    
    
  • 相关阅读:
    【Networking】(转)一个非常好的epoll+线程池服务器Demo
    【算法】Logistic regression (逻辑回归) 概述
    【Linux】/dev/null 2>&1 详解
    单点登录与联合登录
    web项目报outmemory错误解决方案
    hadoop学习之HDFS
    ELK日志分析系统
    基于cookie共享的SSO中的遇到的问题
    oracle的隐式游标
    mysql截取字符串与reverse函数
  • 原文地址:https://www.cnblogs.com/suika/p/9240225.html
Copyright © 2020-2023  润新知