题意

给出一个所有边都和坐标轴平行的多边形,要求画一个周长尽量小的且所有边也和坐标轴平行的多边形把这个多边形围起来.在周长尽量小的前提下,希望围起来的面积尽量小

点数<=1e5,坐标的绝对值<=1e9

分析

对于第一问:我们画的多边形必须到达给出的多边形的横纵坐标的最大和最小值.假设横纵坐标的最大最小值分别为minx,miny,maxx,maxy,那么周长至少为2(maxx-minx+maxy-miny),而且这个下界显然可以达到,画一个矩形即可.
实际上,maxx-minx+maxy-miny会炸int,所以printf("%lld\n",2ll
(maxx-minx+maxy-miny)会WA.
智障选手就是我,我就是智障选手
那么第二问呢?我们知道一个大小为(maxx-minx)*(maxy-miny)的矩形基本不可能是最优解,脑补一下就发现我们可以使得一些边界向里收紧和给出的多边形贴紧,同时周长不变.例如给定一个汉字"凸"形状的多边形,最优解中画的边界紧贴给出的多边形的每一条边界.同时我们也发现有时画的边界不能和某些位置贴紧,例如给定一个汉字"凹"形状的多边形,中间凹下去的地方我们的边界是不能伸进去的(如果把边界画在里面,就不能保证周长最短).
考虑这样计算面积:把x坐标离散化,假设有tot个不同的x坐标,那么我们现在把整个图形切成了tot-1段.显然同一段内上边界是一条不会拐弯的水平直线,下边界也是一条不会拐弯的水平直线,这一段的面积用上下边界纵坐标之差*这一段的横向长度即可.现在我们只需要分别算出每一段的上下边界的高度.由于对称性,现在只考虑上边界.
对于某一段,我们求出这段区间内给定的多边形的最高的一段水平边界的高度.显然这里我们画出的上边界的位置不能比这个高度低,但不一定能够恰好贴着这个高度画.例如"凹".
接下来观察一下规律就好了:最高点一定可以贴着最高点的高度画,然后向两边依次降低.考虑向左边画的情况,如果给定的多边形的某一段边界再向左侧走会有一段更高的边界,那么这里贴着边界画就不合法,只有左边都不比这里高的时候才可以贴着这里画.
实际上,规律可以表示成这样:对于从左到右每一段区间Interval1,Interval2...我们求出每段区间里给定的多边形的最高一段水平边界的高度Height1,Height2...
对于第i段区间,我们求出前i段区间的Height的最大值preMax,求出第i段区间以及之后的区间的Height的最大值sufMax,第i段区间中我们画的边界的高度就是min(preMax,sufMax)
写两棵线段树就好了.
又丑又长常数飞起.

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100005,inf=0x7f7f7f7f;
typedef long long ll;
int x[maxn],y[maxn];
int dict[maxn],seq[maxn];
bool cmp(const int &a,const int &b){return x[a]<x[b];
}
void bemax(int &a,int b){if(a<b)a=b;
}
void bemin(int &a,int b){if(a>b)a=b;
}
int Min[maxn<<2],Max[maxn<<2];
int markmin[maxn<<2],markmax[maxn<<2];
int tot;
void pdmin(int rt){bemin(Min[rt<<1],markmin[rt]);bemin(Min[rt<<1|1],markmin[rt]);bemin(markmin[rt<<1],markmin[rt]);bemin(markmin[rt<<1|1],markmin[rt]);
}
void addmin(int rt,int l,int r,int ql,int qr,int x){if(ql<=l&&r<=qr){bemin(Min[rt],x);bemin(markmin[rt],x);return;}pdmin(rt);int mid=(l+r)>>1;if(ql<=mid)addmin(rt<<1,l,mid,ql,qr,x);if(qr>mid) addmin(rt<<1|1,mid+1,r,ql,qr,x);Min[rt]=min(Min[rt<<1],Min[rt<<1|1]);
}
void pdmax(int rt){bemax(Max[rt<<1],markmax[rt]);bemax(Max[rt<<1|1],markmax[rt]);bemax(markmax[rt<<1],markmax[rt]);bemax(markmax[rt<<1|1],markmax[rt]);
}
void addmax(int rt,int l,int r,int ql,int qr,int x){if(ql<=l&&r<=qr){bemax(Max[rt],x);bemax(markmax[rt],x);return;}pdmax(rt);int mid=(l+r)>>1;if(ql<=mid)addmax(rt<<1,l,mid,ql,qr,x);if(qr>mid) addmax(rt<<1|1,mid+1,r,ql,qr,x);Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);
}
int qmax(int rt,int l,int r,int ql,int qr){if(ql<=l&&r<=qr)return Max[rt];pdmax(rt);int ans=-inf,mid=(l+r)>>1;if(ql<=mid)bemax(ans,qmax(rt<<1,l,mid,ql,qr));if(qr>mid)bemax(ans,qmax(rt<<1|1,mid+1,r,ql,qr));return ans;
}
int qmin(int rt,int l,int r,int ql,int qr){if(ql<=l&&r<=qr)return Min[rt];pdmin(rt);int ans=inf,mid=(l+r)>>1;if(ql<=mid)bemin(ans,qmin(rt<<1,l,mid,ql,qr));if(qr>mid)bemin(ans,qmin(rt<<1|1,mid+1,r,ql,qr));return ans;
}
void Add(int l,int r,int y){if(l>r)swap(l,r);r--;addmin(1,1,tot-1,l,r,y);addmax(1,1,tot-1,l,r,y);
}
int main(){int n;scanf("%d",&n);int minx=inf,maxx=-inf,miny=inf,maxy=-inf;for(int i=1;i<=n;++i){scanf("%d%d",x+i,y+i);minx=min(minx,x[i]);miny=min(miny,y[i]);maxx=max(maxx,x[i]);maxy=max(maxy,y[i]);}x[n+1]=x[1];y[n+1]=y[1];printf("%lld\n",2ll*(maxx-minx)+2ll*(maxy-miny));for(int i=1;i<=n;++i)seq[i]=i;sort(seq+1,seq+n+1,cmp);int old=inf;tot=0;for(int i=1;i<=n;++i){if(old!=x[seq[i]]){++tot;dict[tot]=x[seq[i]];old=x[seq[i]];}x[seq[i]]=tot;}x[n+1]=x[1];memset(markmin,0x7f,sizeof(markmin));memset(Min,0x7f,sizeof(Min));memset(markmax,0xc2,sizeof(markmax));memset(Max,0xc2,sizeof(Max));for(int i=1;i<=n;++i){if(x[i]!=x[i+1])Add(x[i],x[i+1],y[i]);}long long ans=0;for(int i=1;i<tot;++i){int upperbound=min(qmax(1,1,tot-1,1,i),qmax(1,1,tot-1,i,tot-1));int lowerbound=max(qmin(1,1,tot-1,1,i),qmin(1,1,tot-1,i,tot-1));ans=ans+(upperbound-lowerbound)*1ll*(dict[i+1]-dict[i]);}printf("%lld\n",ans);return 0;
}

转载于:https://www.cnblogs.com/liu-runda/p/7106939.html

bzoj2146 Construct相关推荐

  1. bzoj2146 Construct

    题目描述 随着改革开放的深入推进-- 小T家要拆迁了-- 当对未来生活充满美好憧憬的小T看到拆迁协议书的时候,小T从一位大好的社会主义青年变成了绝望的钉子户. 由于小T的家位于市中心,拆迁工作又难以进 ...

  2. 用Construct 2制作入门小游戏~

    今天在软导课上了解到了Construct 2这个神器,本零基础菜鸟决定尝试做一个简单的小游戏(实际上是入门的教程啊= = 首先呢,肯定是到官网下载软件啊,点击我下载~ 等安装完毕后我便按照新手教程开始 ...

  3. leetcode题解:Construct Binary Tree from Preorder and Inorder Traversal (根据前序和中序遍历构造二叉树)...

    题目: Given preorder and inorder traversal of a tree, construct the binary tree. Note: You may assume ...

  4. LeetCode 105 Construct Binary Tree from Preorder and Inorder Traversal-前序中序遍历构造二叉树-Python和Java递归解法

    题目地址:Construct Binary Tree from Preorder and Inorder Traversal - LeetCode Given preorder and inorder ...

  5. C++_可变参数模板到emplace_back再到construct再到forward

    C++_可变参数模板到emplace_back再到construct再到forward 1.可变参数模板 具体定义如下图所示: 编写一个可变参数版本: 1.1sizeof-运算符 2.emplace_ ...

  6. LeetCode: 106. Construct Binary Tree from Inorder and Postorder Traversal

    题目 Given inorder and postorder traversal of a tree, construct the binary tree. Note: You may assume ...

  7. LeetCode: 105. Construct Binary Tree from Preorder and Inorder Traversal

    题目 Given preorder and inorder traversal of a tree, construct the binary tree. Note: You may assume t ...

  8. 【LeetCode】106. Construct Binary Tree from Inorder and Postorder Traversal

    Construct Binary Tree from Inorder and Postorder Traversal Given inorder and postorder traversal of ...

  9. [leetcode] Construct Binary Tree from Preorder and Inorder Traversal

    Construct Binary Tree from Preorder and Inorder Traversal Given preorder and inorder traversal of a ...

  10. [LeetCode]*105.Construct Binary Tree from Preorder and Inorder Traversal

    题目 Given preorder and inorder traversal of a tree, construct the binary tree. Note: You may assume t ...

最新文章

  1. 【转载】C# 获取系统时间及时间格式
  2. 购物中心潮--我的创业之路
  3. 无法访问你试图使用的功能所在的网络位置_[steam实用工具]解决无法访问商店/社区/好友列表的问题...
  4. c语言程序设计 银行整存整取,《C语言程序设计习题试题集》.doc
  5. .NET 深度指南:Colors
  6. 案例:演示out对象的使用及原理分析
  7. Python+OpenCV:高动态范围(High Dynamic Range, HDR)
  8. java 变量 安全访问_访问java变量
  9. 对 BatchNormalization 中 Internal Convariate Shift 的理解
  10. 常见input输入框 点击 发光白色外阴影 focus
  11. 字符编码(一):序言
  12. 6月7日 PowerPoint 版本支持的媒体格式(跨office版本演示需要了解)
  13. PHP使用redis设置锁
  14. 获取git的当前分支名称
  15. Oracle数据库用户密码过期的解决方法
  16. python大麦网抢票_抢票攻略-大麦网
  17. docker下编译mangoszero WOW60级服务端(一)
  18. Cross-lingual Document Retrieval using Regularized Wasserstein Distance
  19. 笔记本运行linux亮度低,关于笔记本linux亮度调节
  20. 【活动预告】说说对 Coding 新一年的期许, Filco 蓝牙无线机械键盘等你拿!

热门文章

  1. 通信业正面临一场巨变,要么滚蛋要么改变
  2. linux 修改自动联网的配置说明
  3. BootStrap--dropdown
  4. 读凤凰网经典语句记录一
  5. 关于游戏中的材质系统
  6. PHP设计模式——观察者模式
  7. [20180819]四校联考
  8. 遍历frame中的表单:
  9. STM32学习笔记(十) CAN通讯测试(环回模式)
  10. maven打包不执行测试用例