P3105 [USACO14OPEN]公平的摄影(正解是乱搞,我却二分了)(+二分答案总结)

照例化简题意:
给定一个01区间,可以把0改成1,问其中最长的01数量相等的区间长度。
额很容易想到前缀和,把w弄成1,h弄成-1,然后求前缀和,然后乱搞就行了。
但是一直不太会乱搞的我却直接想到了二分。
很容易很容易想到:答案有单调性,也就是:
答案肯定是单调不增的
怎么理解呢?
就是:一定存在一个区间长度,使得其-1不是最大,+1不存在,这就是我们要找的东西
而check的思路也就很明确了:
枚举左端点,然后根据二分出的mid(区间假定长度)来找到一个最长区间,然后判断其中白牛的数量是否为非负偶数:
如果白牛改的话,白-1,花+1,这样花牛的数量就比白牛多了2
若存在一个区间符合以上条件,就试着扩大区间(二分里l=mid),不符合就缩小区间,直到搜到答案。
需要注意的是:
如果搜到最后rx-lx达不到二分的区间长度,需要直接break掉,因为这里的答案不合法。
单次check的复杂度是O(n)的,因为lr端点都只遍历了一遍。
二分的复杂度是O(logn)
所以总复杂度就是O(n logn)
代码没什么大难度:
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e6+;
int n;
struct node
{
int x,co;
}a[maxn];
int sum[maxn];
int ans;
int f[maxn];
bool check(int x)
{
int r=;
for(int l=;l<=n;l++)
{
while(a[r].x-a[l].x<x&&r<n)r++;
if(a[r].x-a[l].x<x)break;
if((sum[r]-sum[l-])%==&&sum[r]-sum[l-]>=)return ;
}
return ;
}
bool cmp(node a,node b)
{
return a.x<b.x;
}
int main()
{
//freopen("testdata.in","r",stdin);
scanf("%d",&n);
for(int i=;i<=n;i++)
{
int x;
char f;
cin>>a[i].x>>f;
a[i].co=f=='W'? : -;
}
sort(a+,a+n+,cmp);
for(int i=;i<=n;i++)
sum[i]=sum[i-]+a[i].co;
int l=,r=;
while(l<r-)
{
int mid=l+r>>;
if(check(mid)==)
r=mid;
else
l=mid;
}
//while(check(l))l++;
printf("%d",l);
return ;
}
下面谈谈二分答案:
一般,二分答案常用于:
- 寻找某东西的最大最小值/最小最大值
- 有单调性的答案寻找
而我遇到的二分差不多有三种(主要是check类型):
- 跳石头类型(暴力判断)
- 本题(稍微转化下)
- 传送门(需要手推式子)
但是大体感觉都和跳石头差不多,找到条件,压掉一维O(n)的复杂度,使之变为log。
而二分很常用,很好用,要像想dp那样,经常想到。
下面介绍二分的板子(while内)
二分答案(正整数):
while(l<r-)
{
int mid=l+r>>;
if(check(mid)==)
r=mid;
else
l=mid;
}
while(check(l))l++;(因为输出左端点,而最后如果只更新了r,那么答案不一定正确,毕竟正整数的误差还是蛮大的)
实数域二分:
while((r-l)>0.000000001)
{
double mid=(l+r)/;
if(check(mid)==)
l=mid;
else
r=mid;
}只要精度不出锅应该都没问题
(完)
P3105 [USACO14OPEN]公平的摄影(正解是乱搞,我却二分了)(+二分答案总结)的更多相关文章
- P3105 [USACO14OPEN]公平的摄影Fair Photography
题意翻译 在数轴上有 NNN 头牛,第 iii 头牛位于 xi(0≤xi≤109)x_i\:(0\le x_i\le 10^9)xi(0≤xi≤109) .没有两头牛位于同一位置. 有两种牛:白牛 ...
- luogu 2312 解方程 乱搞+取模
思路非常好想,但是你很难想到去用这个算法,因为这个几乎就是个乱搞~ 我们发现多项式中每一个系数都很大,但是 $m$ 却很小,即最多只用 $10^6$ 个整数需要验证. 我们知道,如果一个数等于 $0$ ...
- HDU 4691 正解后缀数组(暴力也能过)
本来是个后缀数组,考察算法的中级题目,暴力居然也可以水过,就看你跳不跳坑了(c++和G++返回结果就很不一样,关键看编译器) 丝毫不差的代码,就看运气如何了.唯一差别c++还是G++,但正解是后缀数组 ...
- 【BZOJ-4059】Non-boring sequences 线段树 + 扫描线 (正解暴力)
4059: [Cerc2012]Non-boring sequences Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 440 Solved: 16 ...
- Linux 下 netbeans 字体抗锯齿正解
转自:http://leenjewel.blog.163.com/blog/static/601937922010124444051/ 说来这个不难,主要是我看网上有的写的不是很明确,甚至有的写的根本 ...
- HDU 4251 --- 主席树(划分树是正解)
题意:查询区间中位数 思路:模板题,相当于区间第K大的数,主席树可以水过,但划分树是正解.但还没搞明白划分树,先上模板 #include <iostream> #include <c ...
- Android事件模型之interceptTouchEvnet ,onTouchEvent关系正解
首先,看Android的官方文档正解 onInterceptTouchEvent()与onTouchEvent()的机制: 1. down事件首先会传递到onInterceptTouchEvent() ...
- 分享网上搜到的Oracle中对判定条件where 1=1的正解
今天在网上找到了Oracle中对判定条件where 1=1的正解,粘贴出来和大家分享下 1=1 是永恒成立的,意思无条件的,也就是说在SQL语句里有没有这个1=1都可以. 这个1=1常用于应用程序根据 ...
- Redis分布式锁实现方式(附有正解及错误示例)
一.前言 本文内容主要来自博客:https://wudashan.com/2017/10/23/Redis-Distributed-Lock-Implement/,本文用于归纳总结及笔记用途,如有需要 ...
随机推荐
- 服务器配置https协议,三种免费的方法
最近想搞一个网站玩玩,发布网站用https协议已经是大势所趋了.例如微信小程序,不使用https协议根本不让接入.所以,分享一下我尝试过的三种方法. 1.Linux自签(OPENSSL生成SSL自签证 ...
- 如何在Java中创建数组列表
为了在Java中存储动态大小的元素,我们使用了ArrayList.每当添加新元素时,它会自动增加它们的大小.ArrayList实现Java的List接口和Java的Collection的一部分. 由于 ...
- Ubuntu安装exfat工具
sudo apt-get undate sudo apt-get install exfat-utils
- 代码审计-MetInfo 6.0.0 sql注入漏洞
首先漏洞存在于app\system\message\web\message.class.php文件中,变量{$_M[form][id]} 直接拼接在SQL语句中,且验证码检测函数是在SQL语句查询之后 ...
- 掌握git基本功
前言 最近想把代码传到GitHub上,结果我发现的demo的npm全是本地安装,上穿到GitHub要死要死,几百M,然后我就搜了下怎么不上传node_modules弄了半天也没成功,于是准备静下心学一 ...
- python学习-流程控制(四)
学习笔记中的源码:传送门 4.2if分支结构 if语句有三种形式: 如果 if 条件为“真”,程序就会执行 i f条件后面的多条语句:否则就会依次判断 elif 条件,如果 elif 条件为“真”,程 ...
- 【原】iOS开发进阶(唐巧)读书笔记(二)
第三部分:iOS开发底层原理 1.Objective-C对象模型 1.1 isa指针 NSObject.h部分代码: NS_ROOT_CLASS @interface NSObject <NSO ...
- PHP Windows下使用Memcached扩展
github上发现了一个很好用的小文件,能够 模拟出php_memcached.dll的PHP memcached扩展. PHP memcached client 已知PCEL有两个memcache ...
- day26作业
1.整理TCP三次握手.四次挥手图 2.基于TCP开发一款远程CMD程序 客户端连接服务器后,可以向服务器发送命令 服务器收到命令后执行,无论执行是否成功,无论执行几遍,都将执行结果返回给客户端 注意 ...
- 数据结构(十六)模式匹配算法--Brute Force算法和KMP算法
一.模式匹配 串的查找定位操作(也称为串的模式匹配操作)指的是在当前串(主串)中寻找子串(模式串)的过程.若在主串中找到了一个和模式串相同的子串,则查找成功:若在主串中找不到与模式串相同的子串,则查找 ...