• Loj#6473 「ICPC World Finals 2017」不劳而获的钱财 Money for Nothing


    「ICPC WF 2017」不劳而获的钱财 Money for Nothing

    题意转化为:给出在平面直角坐标系上的若干个左下角和右上角,求组成的最大矩形面积。

    那么对于 $ exists B , X_A le X_B$ 且 (Y_A le Y_B) 的左下角 (B) 点显然无意义,右上角类似。

    然后按 (x) 坐标排序,对于相邻的两个左下角 $A_1 , A_2 (X_{A_1} < X_{A_2}) $ 和右上角 (B_1 , B_2 (X_{B_1} < X_{B_2})) ,我们发现如果 (A_1) 的最优决策点在 (B_1) 之后,那么对 (A_2) 来说 (B_2) 也一定比 (B_1) 更优,于是得知决策点是单调的,分治求答案即可。时间复杂度 (O(n log n))

    #include<bits/stdc++.h>
    #define fo(i,a,b) for(register int i=a;i<=b;++i)
    #define fd(i,a,b) for(register int i=a;i>=b;--i)
    #define gc() (BB == BE ? (BE = (BB = BUFF) + fread(BUFF,1,BUFF_SIZE,stdin),BB == BE ? EOF : *BB++) : *BB++) 
    const int BUFF_SIZE = 1 << 20; 
    char BUFF[BUFF_SIZE],*BB,*BE;
    #define ll long long
    using namespace std;
    const int N=5e5+10;
    const ll INF=0x3f3f3f3f3f3f;
    int n,m,cnt1,cnt2,cnt;
    ll ans,Min,Max;
    struct node{
    	ll x,y;
    }a[N],b[N],c[N],d[N];
    inline bool cmp(node a,node b){return a.x<b.x || (a.x==b.x && a.y<b.y);}
    inline bool cmp1(node a,node b){return a.x>b.x || (a.x==b.x && a.y>b.y);}
    inline ll calc(int x,int y){
    	return (b[y].x-a[x].x) * (b[y].y - a[x].y);
    }
    void solve(int l,int r,int L,int R){
    	int mid=l+r>>1;ll ret=-INF,w=0;
    	fo(i,L,R){
    		if(b[i].y<=a[mid].y){
    			if(w)break;
    			if(l<mid)solve(l,mid-1,L,i);
    			if(mid<r)solve(mid+1,r,i,R);
    			return;
    		}
    		ll cur=calc(mid,i);
    		if(cur>ret){
    			ret=cur;
    			w=i;
    		}
    	}
    	ans=max(ans,ret);
    	if(l<mid)solve(l,mid-1,L,w);
    	if(mid<r)solve(mid+1,r,w,R);
    }
    inline int read(){
    	int t=0;
    	char ch=gc();
    	while(ch<'0' || '9'<ch)ch=gc();
    	while('0'<=ch && ch<='9'){
    		t=t*10+ch-'0';
    		ch=gc();
    	}
    	return t;
    }
    int main(){
    	m=read();n=read();
    	fo(i,1,m)
    		c[i].x=read(),c[i].y=read();
    	sort(c+1,c+m+1,cmp);
    	fo(i,1,n)
    		d[i].x=read(),d[i].y=read();
    	sort(d+1,d+n+1,cmp1);
    	Min=INF;Max=-INF;
    	fo(i,1,m){
    		if(c[i].y<Min){
    			Min=c[i].y;
    			a[++cnt1]=c[i];
    		}
    	}
    	fo(i,1,n){
    		if(d[i].y>Max){
    			Max=d[i].y;
    			b[++cnt2]=d[i];
    		}
    	}
    	n=cnt1;m=cnt2;
    	sort(b+1,b+m+1,cmp);
    	solve(1,n,1,m);
    	printf("%lld
    ",ans);
    	
    	return 0;
    }
    
  • 相关阅读:
    Ubuntu 17.10 联网、jdk配置、初始化
    记一次与为知笔记的客服沟通
    C++ Primer zh 5th 思维导图
    《程序员健康指南(The Healthy Programmer)》笔记
    Learn_OpenGL_002_你好,长方形
    Learn_OpenGL_001_环境配置
    Visual Studio Community 2017 配置 OpenGL 环境
    oracle删除数据库
    oracle修改审计功能
    dataguard日志自动删除
  • 原文地址:https://www.cnblogs.com/Kelvin2005/p/15182402.html
Copyright © 2020-2023  润新知