LOJ2758 年轮蛋糕
JOI 君马上要和妹妹 JOI 子和 JOI 美一起吃小吃。今天的小吃是他们三个人都很喜欢的年轮蛋糕。
年轮蛋糕是像下图一样呈圆筒形的蛋糕。为了把蛋糕分给三个人,JOI 君必须沿着半径方向切 3 刀,从而把蛋糕分成三块。然而,由于年轮蛋糕硬得像实木一样,要让刀切进去并不简单。因此,这个年轮蛋糕上事先准备了 N 个切口,而 JOI 君只能在有切口的位置下刀。切口按顺时针顺序编号为 1到 N,对于 1≤i≤N−1,第 i 个切口和第 i+1个切口之间部分的大小是 Ai。第 N 个切口和第 1个切口之间部分的大小是 AN 。

图 1:一个年轮蛋糕的例子,N=6,A1=1,A2=5,A3=4,A4=5,A5=2,A6=4
妹控的 JOI 君在把蛋糕切成 3 块之后,自己选走最小的一块吃掉,把剩下两块分给两个妹妹。而另一方面,JOI 君太喜欢年轮蛋糕了,只要能吃到的时候就会想吃很多很多。试求:最小块的大小不超过多少。
样例说明 1

图 2:从第 1,3,5个切口下刀时是最优解(即图中粗实线位置)。
这道题用二分+二分。我们知道分一个蛋糕需要切三刀,第一刀枚举O(n),第二刀二分logN,第三刀二分logN,一共O(nlogn^2),可以过。
第一、二刀会把最小的一块给切走,然后留下一大块。
然后用第三刀切这一大块,如果这两块切完都比刚才切走的小,说明这一大块无论怎么切都切不出符合的结果,所以开始的一块切大了,第二刀往小切
如果前面一块小于刚切走的,说明第三刀要往后切;
如果后面一块小了,就往前切;
如果两块都可以,说明这种切法可行,第二刀尝试往更大的切。
注意所有数组下表的处理。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <stack>
#define in(a) a=read()
#define MAXN 200020
#define REP(i,k,n) for(long long i=k;i<=n;i++)
using namespace std;
inline long long read(){
long long x=,f=;
char ch=getchar();
for(;!isdigit(ch);ch=getchar())
if(ch=='-')
f=-;
for(;isdigit(ch);ch=getchar())
x=x*+ch-'';
return x*f;
}
long long n;
long long ans;
long long a[MAXN],s[MAXN];
inline bool check(long long i,long long k){
long long sum=s[i+k-]-s[i-];
long long loc=i+k-;
long long left=,right=n;
while(right-left>){
long long mid=(right+left)/;
if(s[loc+mid]-s[loc]<sum && s[i+n-]-s[loc+mid]<sum) return ;
if(s[loc+mid]-s[loc]<sum) left=mid;
if(s[i+n-]-s[loc+mid]<sum) right=mid;
if(s[loc+mid]-s[loc]>=sum && s[i+n-]-s[loc+mid]>=sum) return ;
}
return ;
}
int main(){
in(n);
REP(i,,n){
in(a[i]);
a[i+n]=a[i];
s[i]=s[i-]+a[i];
}
REP(i,,n)
s[i+n]=s[i+n-]+a[i+n];
REP(i,,n){
long long left=,right=n;
while(right-left>){
long long mid=(left+right)/;
if(check(i,mid)) left=mid;
else right=mid;
}
ans=max(s[i+left-]-s[i-],ans);
}
cout<<ans;
return ;
}
LOJ2758 年轮蛋糕的更多相关文章
- 【2018.10.1】「JOI 2014 Final」年轮蛋糕
题面 一看到求“最小值的最大值”这种问题,就能想到二分了. 二分答案,然后我们要把一圈分成三块,使这三块的大小都$\geq mid$.做法是把环展开成2倍长度的链,先钦定一个起点,然后根据前缀和再二分 ...
- sprintf数据库查询的作用
$sql = sprintf("UPDATE file SET mimetype=null,title=null,size=null,protected=null WHERE id=%d&q ...
- 国庆 Day1
This is a 玄学 exam A.年轮蛋糕 最小的最大,二分首选 断环为链,check(x),x为答案,然后将每个大于x的子区间记录下来 如果有大于3个的话,那么x就可以是答案 那么·,在优化下 ...
- JOI2013-2019
代码自己去LOJ看 JOI2013 彩灯 把序列划分成若干极长交替列,那么最优的方案一定是将一个极长交替列翻转使得连续的三个极长交替列合成一个.计算相邻三个极长交替列长度的最大值即可. 搭乘IOI火车 ...
随机推荐
- bzoj 2653 二分答案+可持久化线段树
首先离散化,然后我们知道如果对于一个询问的区间[l1,r1],[l2,r2],我们二分到一个答案x,将[l1,r2]区间中的元素大于等于x的设为1,其余的设为-1,那么如果[l1,r1]的最大右区间和 ...
- Windows降权
使用invoke-tokenmanipulation进行降权 枚举所有令牌 PS C:\Users\SMC> Get-ExecutionPolicy Restricted PS C:\Users ...
- python设计模式之内置装饰器使用(四)
前言 python内部有许多内建装饰器,它们都有特别的功能,下面对其归纳一下. 系列文章 python设计模式之单例模式(一) python设计模式之常用创建模式总结(二) python设计模式之装饰 ...
- docker之构建redis-cluster集群
下载和编译redis安装包 参考:https://www.cnblogs.com/cwp-bg/p/8094914.html # 从官方网站下载安装包,注意,当前在哪个目录下执行命令,下载的包将在哪个 ...
- OC学习篇之---类的延展
来源:http://blog.csdn.net/jiangwei0910410003/article/details/41775603 前一篇文章我们介绍了类的类目概念和使用:http://blog. ...
- PyQt实现测试工具
测试工具: 1. 基本界面实现: # coding:utf-8 import sys import os import os.path import re import time from PyQt4 ...
- C语言使用数学库编译不通过问题
#include <stdio.h>#include <math.h> int main(){ double a = 10.0,b = 3.0; f ...
- java并发编程实战笔记---(第三章)对象的共享
3.1 可见性 synchronized 不仅实现了原子性操作或者确定了临界区,而且确保内存可见性. *****必须在同步中才能保证:当一个线程修改了对象状态之后,另一个线程可以看到发生的状态变化. ...
- javascript当中的this详解
总结this的3个规则: this是调用上下文,上下文被创建或者初始化时才确定 非严格模式:this是全局对象:严格模式:this是undefined 函数调用 a. 以函数形式调用的函数通常不使用t ...
- spring源码分析---IOC(1)
我们都知道spring有2个最重要的概念,IOC(控制反转)和AOP(依赖注入).今天我就分享一下spring源码的IOC. IOC的定义:直观的来说,就是由spring来负责控制对象的生命周期和对象 ...