zoukankan      html  css  js  c++  java
  • 2019牛客多校第⑨场J Symmetrical Painting(思维,离散化)

    原题:https://ac.nowcoder.com/acm/contest/889/J

    题意:

    二维平面上有n个矩形,每个矩形左下角是(i−1,Li)(i−1,Li), 右上角是(i,Ri)(i,Ri),矩形一开始全是黑色,平面不被矩形覆盖的地方是白色,你要把某些黑色区域涂白(一个矩形可以内部颜色不一样),使得黑色区域是一个轴对称图形并且对称轴平行于x轴,求最大黑色区域面积

    思路:

    经过分析发现ans关于对称轴y是一个线性的函数,而函数的最大值点只可能在 中线处取到,因此我们只需要从下往上枚举每条中线,但是y在矩形下半部分移动和在上半部分移动,这个矩形的ans关于y的单调性是相反的,因此我们需要把矩形分为上半部分和下半部分,分别维护两个集合的大小down和up(对称轴在移动过程中经过的部分矩形有多少个),下半部分的集合对答案的贡献就是(down * 移动距离 * 2)​ ,上半部分集合对答案的贡献是(-up * 移动距离 * 2)。
    为了down和up能O(1)快速更新,需要预处理每次移动两个集合的变化。可以将每条边(底线,中线,上线)离散化,从下往上枚举离散化后的坐标,记录每次底线、中线、上线的变化数量。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn=3e5+5;
    int l[maxn],r[maxn],mid[maxn];
    int a[maxn*3];
    int in[maxn*3],out[maxn*3],change[maxn*3];
    int main(){
    	ll n;
    	cin>>n;
    	ll size=0;
    	for(ll i=1;i<=n;i++){
    		scanf("%d%d",&l[i],&r[i]);
    		l[i]=l[i]*2-1;//l[i]<=2e9
    		r[i]=r[i]*2-1;
    		mid[i]=((ll)l[i]+r[i])>>1;
    		a[++size]=l[i];
    		a[++size]=r[i];
    		a[++size]=mid[i];
    	}
    	sort(a+1,a+1+size);
    	size=unique(a+1,a+1+size)-(a+1);
    	for(ll i=1;i<=n;i++){
    		in[lower_bound(a+1,a+1+size,l[i])-a]++;
    		change[lower_bound(a+1,a+1+size,mid[i])-a]++;
    		out[lower_bound(a+1,a+1+size,r[i])-a]++;
    	}
    	ll down=0,up=0;//下半矩形个数和上半矩形个数 
    	ll temp=0,ans=0;
    	down+=in[1];
    	for(ll i=2;i<=size;i++){//第一条是下线,对答案无贡献
    		temp+=((ll)(down-up)*(a[i]-a[i-1]));
    		ans=max(temp,ans);
    		down+=in[i];
    		down-=change[i];
    		up+=change[i];
    		up-=out[i];
    	}
    	printf("%lld
    ", ans);
    }
    
  • 相关阅读:
    移动设备横竖屏判断 CSS 、JS
    Jquery监听value的变化
    设置了line-block的div会出现间隙
    移动端点击可点击元素时,出现蓝色默认背景色
    网页顶部进度条-NProcess.js
    ios UITableView
    ios UIScrollView
    ios Xcode 快捷方式
    ios常用方法、基础语法总结
    Mac eclipse Tomcat安装
  • 原文地址:https://www.cnblogs.com/ucprer/p/11363093.html
Copyright © 2011-2022 走看看