• bzoj4951 [Wf2017]Money for Nothing


    题目描述

    题解:

    答案显然是$max((q-p)*(e-d))$

    依然先贪心。

    对于工厂,我们倾向于$pi<pj,di<dj$的;

    对于买家,我们倾向于$qi>qj,ei>ej$的。

    于是将一定不是最优解的工厂和买家划掉。

    然后我们发现这个东西是满足决策单调性的。

    问我怎么证?画一个二维坐标系,然后将选中的点都画上,然后就理性易证了。

    最后分治。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define N 500050
    #define ll long long
    inline ll rd()
    {
        ll f=1,c=0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){c=10*c+ch-'0';ch=getchar();}
        return f*c;
    }
    int n0,m0,n,m;
    struct Pair
    {
        ll x,y;
        Pair(){}
        Pair(ll x,ll y):x(x),y(y){}
    };
    bool cmp1(Pair a,Pair b)
    {
        if(a.x!=b.x)return a.x<b.x;
        return a.y<b.y;
    }
    bool cmp2(Pair a,Pair b)
    {
        if(a.x!=b.x)return a.x<b.x;
        return a.y>b.y;
    }
    Pair a0[N],b0[N],a[N],b[N];
    ll ans = 0;
    void divi(int l1,int r1,int l2,int r2)
    {
        if(l1>r1||l2>r2)return ;
        if(l1==r1)
        {
            for(int i=l2;i<=r2;i++)
                if(b[i].x>a[l1].x)ans = max(ans,(b[i].x-a[l1].x)*(b[i].y-a[l1].y));
            return ;
        }
        if(l2==r2)
        {
            for(int i=l1;i<=r1;i++)
                if(b[l2].x>a[i].x)ans = max(ans,(b[l2].x-a[i].x)*(b[l2].y-a[i].y));
            return ;
        }
        int mid = (l2+r2)>>1;
        int pos=l1;
        ll max_val=-0x3f3f3f3f3f3f3f3fll;
        for(int i=l1;i<=r1;i++)
        {
            if(b[mid].x<=a[i].x&&b[mid].y<=a[i].y)continue;
            if((b[mid].x-a[i].x)*(b[mid].y-a[i].y)>max_val)
            {
                pos = i;
                max_val=(b[mid].x-a[i].x)*(b[mid].y-a[i].y);
            }
        }
        ans=max(ans,max_val);
        divi(l1,pos,l2,mid-1);
        divi(pos,r1,mid+1,r2);
    }
    int main()
    {
    //  freopen("33.in","r",stdin);
        n0 = rd(),m0 = rd();
        for(int i=1;i<=n0;i++)
            a0[i].x = rd(),a0[i].y = rd();
        for(int i=1;i<=m0;i++)
            b0[i].x = rd(),b0[i].y = rd();
        sort(a0+1,a0+1+n0,cmp1);
        sort(b0+1,b0+1+m0,cmp2);
        ll lim = 0x3f3f3f3f3f3f3f3fll;
        for(int i=1;i<=n0;i++)
            if(a0[i].y<lim)
            {
                a[++n]=a0[i];
                lim = a0[i].y;
            }
        for(int i=1;i<=m0;i++)
        {
            while(m&&b[m].y<=b0[i].y)m--;
            b[++m]=b0[i];
        }
        divi(1,n,1,m);
        printf("%lld
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    机器学习中的规则化
    TF-IDF 文本相似度分析
    数据分析实践:遇到的问题及感想
    记录工作中用到的linux命令
    回归:预测数值型数据
    FP
    Application
    Mac安装sqlite3
    查看百度CUID方法
    leetcode算法题整理
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10218187.html
Copyright © 2020-2023  润新知