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/,本文用于归纳总结及笔记用途,如有需要 ...
随机推荐
- layui navTree 动态渲染菜单组件介绍
navTree.js 简介 extends/navTree.js 是一个基于 layui 扩展的模块化组件,用于构建后台布局系统中的垂直导航菜单与水平导航菜单. extends/navTree.js ...
- SQL Server 2012企业版和标准版的区别
关于使用Microsoft SQL Server 数据库的公司一般会有疑问,企业版数据库和标准版数据库的区别在哪?如果采购企业版的价格和标准版的价格相差很大,从多方资料查询发现,我认为最主要的区别是硬 ...
- unittest中diascover批量执行用例
# case_dir='./'#当前脚本的路径 # discover=unittest.defaultTestLoader.discover(case_dir,pattern='unittest_fr ...
- [Luogu3070][USACO13JAN]岛游记Island Travels
题目描述 Farmer John has taken the cows to a vacation out on the ocean! The cows are living on N (1 < ...
- (20)ASP.NET Core EF创建模型(必需属性和可选属性、最大长度、并发标记、阴影属性)
1.必需和可选属性 如果实体属性可以包含null,则将其视为可选.如果属性的有效值不可以包含null,则将其视为必需属性.映射到关系数据库架构时,必需的属性将创建为不可为null的列,而可选属性则创建 ...
- Python开发【第五篇】字符串
字符串 作用:用来记录文字信息 例子: 空字符串 '' #单引号空字符串 "" #双引号空字符串 ''' ''' #三单引号空字符串 """ &quo ...
- Jackson替换fastjson
为什么要替换fastjson 工程里大量使用了fastjson作为序列化和反序列化框架,甚至ORM在处理部分字段也依赖fastjson进行序列化和反序列化.那么作为大量使用的基础框架,为什么还要进行替 ...
- js初学者循环经典题目
1.根据一个数字日期,判断这个日期是这一年的第几天例如: 2016和02和11,计算后结果为42 var y = 2016;//+prompt("请输入年份") ; ...
- 使用animate.css
今天有个一前辈来看了一下我的小程序啊,说写的还行就是可以不用只按照ui给的图写界面,自己可以添加一些动态的炫酷效果,不用不知道一用吓一跳啊,用之前觉得好好一个界面为什么要搞那些花里胡哨的东西,单纯一点 ...
- Linux下终端字体颜色设置方法
颜色=\033[代码;前景;背景m 如:\033[1;32;40m表示高亮显示字体为绿色,背景色为黑色 颜色=\[\033[代码;前景;背景m\] echo -e "this is a \0 ...