传送门

就是给出一个矩形,上面有一些点,让你找出一个周长最大的矩形,满足没有一个点在矩形中。

这个题很有意思。

考虑到答案一定会穿过中线。

于是我们可以把点分到中线两边。

先想想暴力如何解决。

显然就是枚举矩形的上下边的坐标然后求两边的最大宽度。

用单调栈搞一下这样的效率是O(n2)O(n^2)O(n2)的。

考虑继续优化。

干脆我们只枚举一条边,另外一条用线段树维护最值。

代码:

#include<bits/stdc++.h>
#define N 300005
#define lc (p<<1)
#define rc (p<<1|1)
#define mid (T[p].l+T[p].r>>1)
using namespace std;
int w,h,n,top1,top2,ans;
struct Pot{int x,y;}p[N];
struct Node{int l,r,mx,add;}T[N<<2];
struct node{int id,val;}stk1[N],stk2[N];
inline int max(int a,int b){return a>b?a:b;}
inline void pushnow(int p,int v){T[p].mx+=v,T[p].add+=v;}
inline void build(int p,int l,int r){
	T[p].l=l,T[p].r=r,T[p].mx=T[p].add=0;
	if(l==r)return;
	build(lc,l,mid),build(rc,mid+1,r);
}
inline void update(int p,int ql,int qr,int v){
	if(T[p].l>qr||T[p].r<ql)return;
	if(ql<=T[p].l&&T[p].r<=qr)return pushnow(p,v);
	if(T[p].add)pushnow(lc,T[p].add),pushnow(rc,T[p].add),T[p].add=0;
	if(qr<=mid)update(lc,ql,qr,v);
	else if(ql>mid)update(rc,ql,qr,v);
	else update(lc,ql,mid,v),update(rc,mid+1,qr,v);
	T[p].mx=max(T[lc].mx,T[rc].mx);
}
inline void swap(int&x,int&y){x^=y,y^=x,x^=y;}
inline bool cmp(Pot a,Pot b){return a.x<b.x;}
inline void solve(){
	sort(p+1,p+n+1,cmp),build(1,1,n),top1=top2=0;
	for(int i=1;i<=n;++i){
		int las=i-1;
		if(p[i].y<=h/2){
			while(top1&&stk1[top1].val<p[i].y){
				update(1,stk1[top1].id,las,stk1[top1].val-p[i].y);
				las=stk1[top1--].id-1;
			}
			if(las!=i-1)stk1[++top1]=(node){las+1,p[i].y};
		}
		else{
			while(top2&&stk2[top2].val>p[i].y){
				update(1,stk2[top2].id,las,p[i].y-stk2[top2].val);
				las=stk2[top2--].id-1;
			}
			if(las!=i-1)stk2[++top2]=(node){las+1,p[i].y};
		}
		stk1[++top1]=(node){i,0},stk2[++top2]=(node){i,h};
		update(1,i,i,h-p[i].x),ans=max(ans,T[1].mx+p[i+1].x);
	}
}
inline int read(){
	int ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans;
}
int main(){
	w=read(),h=read(),n=read();
	for(int i=1;i<=n;++i)p[i].x=read(),p[i].y=read();
	p[++n]=(Pot){0,0},p[++n]=(Pot){w,h};
	solve();
	for(int i=1;i<=n;++i)swap(p[i].x,p[i].y);
	swap(w,h);
	solve();
	cout<<ans*2;
	return 0;
}

2018.09.22 atcoder Snuke's Coloring 2(线段树+单调栈)的更多相关文章

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

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

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

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

  3. 2018.09.22 atcoder Integers on a Tree(构造)

    传送门 先考虑什么时候不合法. 第一是考虑任意两个特殊点的权值的奇偶性是否满足条件. 第二是考虑每个点的取值范围是否合法. 如果上述条件都满足的话就可以随便构造出一组解. 代码: #include&l ...

  4. 2018.09.19 atcoder Snuke's Subway Trip(最短路)

    传送门 就是一个另类最短路啊. 利用颜色判断当前节点的最小花费的前驱边中有没有跟当前的边颜色相同的. 如果有这条边费用为0,否则费用为1. 这样跑出来就能ac了. 代码: #include<bi ...

  5. 2018.08.22 hyc的xor/mex(线段树/01trie)

    hyc的xor/mex 描述 NOIP2017就要来了,备战太累,不如做做hyc的新题? 找回自信吧! 一句话题意:n个数,m个操作 操作具体来讲分两步 1.读入x,把n个数全部xor上x 2.询问当 ...

  6. 2018.09.22 上海大学技术分享 - An Introduction To Go Programming Language

    老实说笔者学习 Go 的时间并不长,积淀也不深厚,这次因缘巧合,同组的同事以前是上海大学的开源社区推动者之一,同时我们也抱着部分宣传公司和技术分享的意图,更进一步的,也是对所学做一个总结,所以拟定了这 ...

  7. 【arc073e】Ball Coloring(线段树,贪心)

    [arc073e]Ball Coloring(线段树,贪心) 题面 AtCoder 洛谷 题解 大型翻车现场,菊队完美压中男神的模拟题 首先钦定全局最小值为红色,剩下的袋子按照其中较大值排序. 枚举前 ...

  8. 2018.07.03 HDU Rikka with Phi(线段树)

    Rikka with Phi Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) P ...

  9. Atcoder E - Meaningful Mean(线段树+思维)

    题目链接:http://arc075.contest.atcoder.jp/tasks/arc075_c 题意:问数组a有多少子区间平均值为k 题解:一开始考虑过dp,但是显然不可行,其实将每一个数都 ...

随机推荐

  1. 前端-CSS-3-高级选择器

    高级选择器 总结: <!-- 总结: 基础选择器: 1.标签选择器 div 2.类选择器 .div1 3.id选择器 #box 4.通配符选择器 * 高级选择器: 1.群组选择器 中间用, .t ...

  2. app.$mount("#app") 手动挂载

    $mount()手动挂载 当Vue实例没有el属性时,则该实例尚没有挂载到某个dom中: 假如需要延迟挂载,可以在之后手动调用vm.$mount()方法来挂载.例如: new Vue({ //el: ...

  3. MySQL 事务 是对数据进行操作,对结构没有影响,比如创建表、删除表,事务就不起作用

  4. 一行转多行 及多行转一行的 hive语句

      注意 :|,: 是特殊符号,要用 "\\|", "\\;"来表示.   一行转多行 usertags 里面有很多项,每项之间以逗号分隔   create t ...

  5. Concurrency and Race Conditions

    1.当多个线程访问共享硬件或软件资源的任何时候,由于线程之间可能产生对资源的不一致观察,所以必须显式管理对资源的访问. 2.内核中的并发管理设施: (1). 信号量: P操作将信号量的值减 1 ,判断 ...

  6. Eletron 打开文件夹,截图

    1.shell.openItem(fullPath) var fullpath = path.join(processPath)+Math.random()+".png"; she ...

  7. dubbo dubbo.xsd 报错

    构建dubbo项目的时候会遇到: Multiple annotations found at this line: - cvc-complex-type.2.4.c: The matching wil ...

  8. Go语言中cannot convert adminname (type interface {}) to type *: need type assertion的解决办法

    解决的办法是把string(adminname)替换为adminname.(string).其它类型也是类似.

  9. java基础四 [构造器和垃圾回收](阅读Head First Java记录)

    本章讲解了对象的创建到被回收的过程,讲述了对象的生命周期   堆(heap)与栈(stack) 实例变量:实例变量是只声明在类下,方法外的变量(实例变量默认值为0/0.0/false,引用的默认值为n ...

  10. java重载(实现同一方法名,不同参数)

    背景:  前几天写连接数据库时,因为要执行sql,有的是指向得到所有的执行结果,有的是想根据执行结果获得某一个字段的结果.这时我想通过同一个方法名,不同的参数,获得不同的结果.结果发现java的方法竟 ...