【AtCoder】【模型转化】【二分答案】Median Pyramid Hard(AGC006)
题意:
给你一个排列,有2*n-1个元素,现在进行以下的操作:
每一次将a[i]替换成为a[i-1],a[i],a[i+1]三个数的中位数,并且所有的操作是同时进行的,也就是说这一次用于计算的a[],是这一次计算之前的那个a[]。每一次不操作开头和结尾的两个位置。这样子每一次都会减少2个元素,问你最后剩下的元素是什么。
数据范围:
1<=N<=10^5
思路:
看见这道题正解是二分的时候,简直震惊!(考试的时候一直想的是计算每一项在最终序列中的系数来做)。
我们可以二分出一个值x,将所有小于等于x的数都变为0,将所有的大于x的数都变为1,然后再来看待这个问题。
下面建议读者一边画图一边来看。
首先定义一种状态,叫做柱子。也就是当存在连续的两个相同的数字的时候,这两个数字的上方会连续出现两个一样的数字,直到成为最左边或者是最右边的数字而被删除为止。
我们考虑哪些状态下,顶层的数字会是0。假如说这个问题解决了,就可以二分了。
- 顶端的正下方就有一根值为0的柱子,这个时候根据柱子的定义是显然成立的;
- 顶端的左边或者是右边有一根值为0的柱子,而另一边没有柱子。如果你画一下图就会发现,对于没有柱子的区域而言,那么必定是0101010...交错排列的。那么当前的这根0的柱子就能够保证到达某一层之后,右边的端点一定是0。这个时候就可以划归到第5种情况了;
- 顶端的两端都有柱子,且都是0的柱子。如果说状态2成立的话,那么这个也是显然成立的;
- 顶端的两端都有柱子,且一边最靠近顶端的柱子值为0,令一端最靠近顶端的柱子值为1,并且要求0柱子更加靠近1柱子。这个比较好想。到达某一层之后,1的柱子消失了,而这个时候0柱子至少还存在1个,且存在1个的时候还是再端右端点上。那么仍然能够划归到情况5;
- 顶端的两端都没有柱子,且底层的两端都是0,也就是num0=num1+1。如果稍微画一下图你就能发现,这样子0101010交错着上去,每一层都是这样子交错的,且都是两端为0。那么这样子到了次顶端的时候必定是010,然后顶端就是0了。
这样子对于一个01的序列直接O(n)判断就好了,总时间为O(nlogn)。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 100000
using namespace std;
int N,a[2*MAXN+5];
bool seq[2*MAXN+5];
int Check(int x)
{
for(int i=1;i<=2*N-1;i++)
if(a[i]<=x)
seq[i]=0;
else
seq[i]=1;
if(seq[N]==seq[N-1]||seq[N]==seq[N+1])
return seq[N];//判断顶端的正下方有没有柱子
int l=-1,r=-1;
int ld,rd;
for(int i=2;i<=N;i++)
if(seq[i]==seq[i-1])
l=seq[i],ld=N-i+1;//计算左边的柱子类型以及距离
for(int i=N;i<2*N-1;i++)
if(seq[i]==seq[i+1])
{
r=seq[i];//计算右边的柱子类型以及距离
rd=i-N+1;
break;
}
if((l==0&&r==-1)||(l==-1&&r==0)||(l==0&&r==0))//情况2和3
return 0;
if((l==1&&r==0&&ld>rd)||(l==0&&r==1&&ld<rd))//情况4
return 0;
if(l==-1&&r==-1&&seq[1]==0)//情况5
return 0;
return 1;
}
int main()
{
// freopen("mid.in","r",stdin);
// freopen("mid.out","w",stdout);
scanf("%d",&N);
for(int i=1;i<=2*N-1;i++)
scanf("%d",&a[i]);
int L=0,R=2*N;
while(L<R)
{
int mid=(L+R)/2;
if(Check(mid)==0)//O(n)判断
R=mid;
else
L=mid+1;
}
printf("%d\n",R);
return 0;
}
【AtCoder】【模型转化】【二分答案】Median Pyramid Hard(AGC006)的更多相关文章
- Atcoder Grand Contest 006 D - Median Pyramid Hard(二分+思维)
Atcoder 题面传送门 & 洛谷题面传送门 u1s1 Atcoder 不少思维题是真的想不出来,尽管在 Atcoder 上难度并不高 二分答案(这我倒是想到了),检验最上面一层的数是否 \ ...
- AtCoder Regular Contest 101 (ARC101) D - Median of Medians 二分答案 树状数组
原文链接https://www.cnblogs.com/zhouzhendong/p/ARC101D.html 题目传送门 - ARC101D 题意 给定一个序列 A . 定义一个序列 A 的中位数为 ...
- Leetcode 4 Median of Two Sorted Arrays 二分查找(二分答案+二分下标)
貌似是去年阿里巴巴c++的笔试题,没有什么创新直接照搬的... 题意就是找出两个排序数组的中间数,其实就是找出两个排序数组的第k个数. 二分答案,先二分出一个数,再用二分算出这个数在两个排序数组排序第 ...
- POJ 3579 Median(二分答案+Two pointers)
[题目链接] http://poj.org/problem?id=3579 [题目大意] 给出一个数列,求两两差值绝对值的中位数. [题解] 因为如果直接计算中位数的话,数量过于庞大,难以有效计算, ...
- POJ 3579 Median 【二分答案】
<题目链接> 题目大意: 给出 N个数,对于存有每两个数的差值的序列求中位数,如果这个序列长度为偶数个元素,就取中间偏小的作为中位数. 解题分析: 由于本题n达到了1e5,所以将这些数之间 ...
- 2018.10.14 NOIP训练 直线(二分答案+st表+切比雪夫距离转化)
传送门 二分答案好题. 这已经是当年普及组模拟时挖的坑了233. 这道题还是很不错的. 考虑把坐标系转个45度再操作. 为了不爆精度可以直接转切比雪夫距离. 然后就直接二分答案. 其中竖线就按二分的答 ...
- 【AtCoder Grand Contest 007E】Shik and Travel [Dfs][二分答案]
Shik and Travel Time Limit: 50 Sec Memory Limit: 512 MB Description 给定一棵n个点的树,保证一个点出度为2/0. 遍历一遍,要求每 ...
- [AGC006] D - Median Pyramid Hard 二分
Description 现在有一个NN层的方块金字塔,从最顶层到最底层分别标号为1...N1...N. 第ii层恰好有2i−12i−1个方块,且每一层的中心都是对齐的. 这是一个N=4N=4的 ...
- 【二分答案】【POJ3122】【Northwestern Europe 2006】Pie
Pie Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10629 Accepted: 3744 Special Ju ...
- BZOJ_2600_[Ioi2011]ricehub_二分答案
BZOJ_2600_[Ioi2011]ricehub_二分答案 Description 乡间有一条笔直而长的路称为“米道”.沿着这条米道上 R 块稻田,每块稻田的坐标均 为一个 1 到 L 之间(含 ...
随机推荐
- pta寒假作业3
题目三:捉老鼠啊,亏了还是赚了 实验代码 #include <stdio.h> #include <stdlib.h> int main(void) { ...
- VMWare的host-only/bridged/NAT连接图文介绍
1 VMware简介 VMWare虚拟机软件是一个“虚拟PC”软件,它使我们可以在一台机器上同时运行二个或更多Windows.Linux等系统. 如果我们需要使用多个系统的话,传统的方式有两种: .使 ...
- canvas绘图工具
关于canvas绘图,在html页面上太方便了.当然刚开始还是入了不少坑,用了比如jcanvascript等三方插件.真实效果反而不理想,后来就没用插件. 下面是实现效果,可以在线绘制工地图然后传给后 ...
- NOI-OJ 2.2 ID:6261 汉诺塔
思路 汉诺塔是递归思想最经典的例子,通过递归不断缩小问题,将n个盘子的问题简化n-1个,直至1个. 三个盘子,分别为A:from,B:to,C:by(A为起点盘,B为目标盘,C为中转盘) 过程 将1- ...
- artDialog记录
//在子页面加按钮的方式 var api = frameElement.api, W = api.opener; api.button({ id: 'valueOk', name: '确定', cal ...
- swoole简单demo测试
测试代码 1.server.php: <?php $serv = new swoole_server("0.0.0.0", 9502); $serv->on('conn ...
- 使用Roslyn编译项目的示例
using System; using System.Collections.Generic; using System.IO; using Microsoft.CodeAnalysis; using ...
- MyBatis联表查询
MyBatis逆向工程主要用于单表操作,那么需要进行联表操作时,往往需要我们自己去写sql语句. 写sql语句之前,我们先修改一下实体类 Course.java: public class Cours ...
- 主机服务绑定IP
在用 netstat -na 查看当前主机提供的服务,例如显示如下结果: tcp 0 0 127.0.0.1:9000 0.0.0.0:* ...
- oracle用命令创建表空间、用户,并为用户授权、收回权限。
oracle中如何删除用户? Oracle中使用DROP USER来删除用户,如果使用DROP USER CASCADE那么用户的对象也同时被删除掉.为了达到删除用户的效果而又不影响对用户下的对象的使 ...