[Arc063F] Snuke's Coloring 2

题目大意

给你一个网格图,一些点上有标记,求边长最大空白矩形。

试题分析

专门卡\(\log^2 n\)系列。

首先由题意我们可以找到答案的下界:\(\min(H,W)\times 2+2\)。

那么就是说这个矩形的周长如果要大于下界肯定会跨越中轴线\(H\)或\(W\),那么我们只需要在两边枚举即可。

这个东西看起来没什么用,我们姑且将其当作常数优化,但是在后面的讨论中它极大地简化了问题。

继续考虑传统扫描线的方向,那么看看当我们确定了任意一个边界的时候可以干什么。

假定这里枚举的是右边界,然后左边界又没有东西可以维护了,那就直接让线段树维护:枚举右边界到点\(i\),左边界为下标时的周长最大值。

现在就是扫描线的问题了,既然维护的是右边界和左边界,那么就肯定按照x轴从左向右扫。

对于上下界的部分,对于每个点维护两个单调栈,方向如下图。

但是这样一来的话就需要开主席树模拟单调栈,相当恶心,并且多了一个log。

怎么办呢?上面我们说过,这个矩形肯定会跨越中轴线,也就是说,我们只需要在中轴线上面维护一个,在下面维护一个单调栈就足够了。

于是,我们的矩形变成了这个样子:

那么下面就是考虑在单调栈进出的时候去更新线段树了,这里建议画一下图:

  • 我们枚举点并加入左边界的考虑部分,因为这个点相对于上一个点会向上移动,加入这个点的时候首先需要弹掉单调队列在它下面的点,然后要把编号在\({id_{stack_{top}}}\)和\({id_{stack_{last\space top}}}\)之间的这些点都减去\(y_i-y_{id_{stack_{top}}}\),因为需要将当前右边界转到下一个点上去。
  • 对于上面也是相同,只需要维护一个如图反着的单调队列即可。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<algorithm>
//#include<ctime>
//#include<cmath>
//#include<queue> using namespace std;
#define LL long long inline LL read(){
LL x=0,f=1; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) x=x*10+c-'0';
return x*f;
}
const LL INF = 2147483600;
const LL MAXN = 500010; struct data{
LL x,y;
}p[MAXN+1],a[MAXN+1],b[MAXN+1];
data make_data(LL xx,LL yy){
data a; a.x=xx; a.y=yy; return a;
}
LL N,W,H;
LL tag[MAXN<<2],tr[MAXN<<2];
bool cmp(data a,data b){
if(a.x!=b.x) return a.x<b.x;
return a.y<b.y;
}
inline void tage_lazy(LL rt){
if(!tag[rt]) return ;
tag[rt<<1]+=tag[rt]; tag[rt<<1|1]+=tag[rt];
tr[rt<<1]+=tag[rt]; tr[rt<<1|1]+=tag[rt];
tag[rt]=0;
return ;
}
inline void update(LL rt,LL l,LL r,LL L,LL R,LL k){
if(L>R) return ;
if(L<=l&&R>=r){tr[rt]+=k; tag[rt]+=k; return ;} tage_lazy(rt);
LL mid=(l+r)>>1; if(L<=mid) update(rt<<1,l,mid,L,R,k);
if(R>mid) update(rt<<1|1,mid+1,r,L,R,k);
tr[rt]=max(tr[rt<<1],tr[rt<<1|1]); return ;
} LL ans=0; inline void work(){
sort(p+1,p+N+1,cmp);
memset(tr,0,sizeof(tr));
memset(tag,0,sizeof(tag));
LL l=0,r=0;
for(LL i=1;i<=N;i++){
if(p[i].y<=(H>>1)){
LL lat=i-1;
while(l&&a[l].y<p[i].y){
update(1,1,N,a[l].x,lat,a[l].y-p[i].y);
lat=a[l].x-1; --l;
} if(lat!=i-1){
a[++l]=make_data(lat+1,p[i].y);
}
} else{
LL lat=i-1;
while(r&&b[r].y>p[i].y){
update(1,1,N,b[r].x,lat,p[i].y-b[r].y);
lat=b[r].x-1; --r;
} if(lat!=i-1){
b[++r]=make_data(lat+1,p[i].y);
}
} a[++l]=make_data(i,0);
b[++r]=make_data(i,H); update(1,1,N,i,i,H-p[i].x);
ans=max(ans,tr[1]+p[i+1].x);
} return ;
} int main(){
//freopen("a.in","r",stdin);
//freopen(".out","w",stdout);
W=read(),H=read(); N=read();
for(LL i=1;i<=N;i++){
p[i].x=read(),p[i].y=read();
} p[++N].x=0; p[N].y=0; p[++N].x=W; p[N].y=H; work(); swap(W,H);
for(LL i=1;i<=N;i++){
swap(p[i].x,p[i].y);
} work(); printf("%lld\n",ans*2);
return 0;
}

[Arc063F] Snuke's Coloring 2的更多相关文章

  1. [arc063F]Snuke's Coloring 2-[线段树+观察]

    Description 传送门 Solution 我们先不考虑周长,只考虑长和宽. 依题意得答案下限为max(w+1,h+1),并且最后所得一定是个矩形(矩形内部无点). 好的,所以!!!答案一定会经 ...

  2. ARC063F すぬけ君の塗り絵 2 / Snuke's Coloring 2

    题面 一句话题面:给你一些点,求这些点之中夹的最大的矩形周长.(考虑边界) Solution 首先是一个结论,答案矩形一定经过\(x=\frac{w}{2}\)或经过\(y=\frac{h}{2}\) ...

  3. 【ARC 063F】Snuke's Coloring 2

    Description There is a rectangle in the xy-plane, with its lower left corner at (0,0) and its upper ...

  4. すぬけ君の塗り絵 / Snuke's Coloring AtCoder - 2068 (思维,排序,贡献)

    Problem Statement We have a grid with H rows and W columns. At first, all cells were painted white. ...

  5. Snuke's Coloring 2-1

    There is a rectangle in the xy-plane, with its lower left corner at (0,0) and its upper right corner ...

  6. AtCoder Regular Contest 063 F : Snuke’s Coloring 2 (线段树 + 单调栈)

    题意 小 \(\mathrm{C}\) 很喜欢二维染色问题,这天他拿来了一个 \(w × h\) 的二维平面 , 初始时均为白色 . 然后他在上面设置了 \(n\) 个关键点 \((X_i , Y_i ...

  7. 2018.09.22 atcoder Snuke's Coloring 2(线段树+单调栈)

    传送门 就是给出一个矩形,上面有一些点,让你找出一个周长最大的矩形,满足没有一个点在矩形中. 这个题很有意思. 考虑到答案一定会穿过中线. 于是我们可以把点分到中线两边. 先想想暴力如何解决. 显然就 ...

  8. 2018.09.19 atcoder Snuke's Coloring(思维题)

    传送门 谁能想到这道题会写这么久. 本来是一道很sb的题啊. 就是每次选一个点只会影响到周围的九个方格,随便1e9进制就可以hash了,但是我非要作死用stl写. 结果由于技术不够高超,一直调不出来. ...

  9. [atARC063F]Snuke's Coloring 2

    首先,可以通过将所有$x_{i}=0$都选择第1类,其余选第2类,构造出一个以$(0,0)$和$(1,h)$为左下角和右上角的矩形,答案即为$2h+2$,类似地还可以构造出$2w+2$ 若最终的矩形不 ...

随机推荐

  1. std::max 错误

    Today I typed the following: int t = (std::max)(timeout, lagtime); Why did I put parentheses around ...

  2. AopProxyUtils.getSingletonTarget(Ljava/lang/Object;)Ljava/lang/Object;大坑

    这个问题太坑了,试了好多个版本,都是依赖冲突导致的, https://blog.csdn.net/qq_15003505/article/details/78430595 最后找到这一篇博客解决了,就 ...

  3. Linux input子系统学习总结(三)----Input设备驱动

    Input 设备驱动 ---操作硬件获取硬件寄存器中设备输入的数据,并把数据交给核心层: 一 .设备驱动的注册步骤: 1.分配一个struct  input_dev :          struct ...

  4. collision

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAd0AAACYCAIAAAAuvaRSAAAAA3NCSVQICAjb4U/gAAAgAElEQVR4Xu

  5. http请求与传参

    这并不算是文章,暂时只做粗略地记录,以免忘记,因此会显得杂乱无章,随便抓了几个包和对postman截图,日后有空再完善 1.get方式 只有一种方式,那就是在url后面跟参数 2.post方式 1)表 ...

  6. java基础58 JavaScript的几种格式和变量的声明方式(网页知识)

    1.JavaScript的几种格式 1.1.JavaScript的特点 1.跨平台性    2.安全性.(javaScript代码不能直接访问电脑硬盘上的信息) 1.2.Java与javaScript ...

  7. CF1030A 【In Search of an Easy Problem】

    题目巨简单,主要是给大家翻译一下 给n个数,其中存在1就输出HARD,否则输出EASY,不区分大小写 #include<iostream> #include<cstdio> u ...

  8. 编程六月定律 | 外刊IT评论网

    编程六月定律 上周,我被迫对一个很老的项目做一些修改.麻烦是,当开始着手时,我真的记不清这个项目究竟有多老了. 这实际上是我使用Codeigniter实现的第一个MVC项目.打开项目文件后,很多东西都 ...

  9. Mac OS 下安装mysqlclient报“mysql_config not found”的解决

    如问题所示,应该是你没有将mysql_config所在文件夹加入系统的PATH路径,解决方案下: 1.第一步找到你的mysql_config所在位置 1.1. 如果是直接安装mysql,所在位置应该是 ...

  10. CVE-2013-0025

    Microsoft IE ‘SLayoutRun’释放后重用漏洞(CNNVD-201302-197) Microsoft Internet Explorer是微软Windows操作系统中默认捆绑的WE ...