Description

Farmer John is preparing a delicious meal for his cows! In his barn, he has NN haybales (1≤N≤100,0
00). The iith haybale has a certain flavor Fi (1≤Fi≤10^9) and a certain spiciness Si(1≤Si≤10^9).
The meal will consist of a single course, being a contiguous interval containing one or more consecu
tive haybales (Farmer John cannot change the order of the haybales). The total flavor of the meal is
 the sum of the flavors in the interval. The spiciness of the meal is the maximum spiciness of all h
aybales in the interval.Farmer John would like to determine the minimum spiciness his single-course 
meal could achieve, given that it must have a total flavor of at least MM (1≤M≤10^18).
给长度为n<=1e5的两个序列f[], s[] <= 1e9和一个long long M。
如果[1, n] 的一个子区间[a, b]满足 f[a]+f[a+1]+..+f[b] >= M, 我们就称[a, b]合法
,一个合法区间[a, b]的值为max(s[a], s[a+1], ..., s[b])。
让你求出可能的合法区间最小值为多少。
 

Input

The first line contains the integers N and M, 
the number of haybales and the minimum total flavor the meal must have, respectively. 
The next N lines describe the N haybales with two integers per line, 
first the flavor F and then the spiciness S.
 

Output

Please output the minimum spiciness in a single course meal that satisfies the minimum flavor requirement. 
There will always be at least one single-course meal that satisfies the flavor requirement.
 

Sample Input

5 10
4 10
6 15
3 5
4 9
3 6

Sample Output

9

Solution

开始敲了要2kb的线段树

然后过了之后幡然醒悟发现只要二分就好了

于是敲了一个代码量很短的二分,还跑快了一倍多

线段树做法

因为一段区间的值是一个$max$,所以我们只需要关心这个$max$

于是可以排序一下,按照每个点的权值来插入线段树里面

用线段树维护最大子段和

每次插入后查一下整棵树的最大子段和有没有超过$m$,超过直接输出当前插入的数的权值就行了

维护最大子段和的线段树的$pushup$写的是真的恶心

#include <cstdio>
#include <cstring>
#include <algorithm> #define N 100010
#define inf 0x3f3f3f3f
#define ll long long
#define lc ( rt << 1 )
#define rc ( rt << 1 | 1 ) using namespace std ; int n ;
ll m ;
struct node {
int s , f , id ;
} a[ N ] ;
struct tree {
int l , r ;
ll ls , rs , sum ;
bool flag ;
} t[ N << ] ; bool cmp( node a , node b ) {
return a.s < b.s ;
} void build( int l , int r , int rt ) {
t[ rt ].l = l ; t[ rt ].r = r ;
t[ rt ].ls = t[ rt ].rs = t[ rt ].sum = t[ rt ].flag = ;
if( l == r ) return ;
int mid = ( l + r ) >> ;
build( l , mid , lc ) ;
build( mid + , r , rc ) ;
} void pushup( int rt ) {
if( t[ lc ].flag && t[ rc ].flag ) {
t[ rt ].flag = ;
t[ rt ].sum = t[ rt ].ls = t[ rt ].rs = t[ lc ].sum + t[ rc ].sum ;
return ;
}
t[ rt ].ls = t[ lc ].ls ;
t[ rt ].rs = t[ rc ].rs ;
if( t[ lc ].flag ) t[ rt ].ls += t[ rc ].ls ;
if( t[ rc ].flag ) t[ rt ].rs += t[ lc ].rs ;
t[ rt ].sum = max( t[ lc ].sum , t[ rc ].sum ) ;
t[ rt ].sum = max( t[ rt ].sum , t[ lc ].rs + t[ rc ].ls ) ;
} void upd( int L , int val , int rt ) {
int l = t[ rt ].l , r = t[ rt ].r , mid = ( l + r ) >> ;
if( l == r ) {
t[ rt ].ls = t[ rt ].rs = t[ rt ].sum = val ;
t[ rt ].flag = ;
return ;
}
if( L <= mid ) upd( L , val , lc ) ;
else upd( L , val , rc ) ;
pushup( rt ) ;
} int main() {
scanf( "%d%lld" , &n , &m ) ;
for( int i = ; i <= n ; i ++ ) {
scanf( "%d%d" , &a[ i ].f , &a[ i ].s ) ;
a[ i ].id = i ;
}
sort( a + , a + n + , cmp ) ;
build( , n , ) ;
for( int i = ; i <= n ; i ++ ) {
upd( a[ i ].id , a[ i ].f , ) ;
if( t[ ].sum >= m ) {
printf( "%d\n" , a[ i ].s ) ;
return ;
}
}
}

二分做法

其实可以二分这个最大值(即答案)

然后每次$check$的时候$O(n)$扫一遍,看看最大子段和(段内点权不包括大于这个二分的值)会不会大于$m$

答案是具有单调性的所以可以二分

跑的飞快

#include <cstdio>
#include <algorithm> using namespace std ; #define N 100010
#define ll long long int a[ N ] , b[ N ] ;
int n ;
ll m ; bool check( int x ) {
ll sum = ;
for( int i = ; i <= n ; i ++ ) {
if( b[ i ] > x ) {
sum = ;
continue ;
}
sum += a[ i ] ;
if( sum >= m ) return ;
}
return ;
} int main() {
scanf( "%d%lld" , &n , &m ) ;
for( int i = ; i <= n ; i ++ ) {
scanf( "%d%d" , &a[ i ] , &b[ i ] ) ;
}
int l = , r = 1e9+ , ans = ;
while( l <= r ) {
int mid = ( l + r ) >> ;
if( check( mid ) ) ans = mid , r = mid - ;
else l = mid + ;
}
printf( "%d\n" , ans ) ;
}

BZOJ5142: [Usaco2017 Dec]Haybale Feast 线段树或二分答案的更多相关文章

  1. BZOJ5142: [Usaco2017 Dec]Haybale Feast(双指针&set)(可线段树优化)

    5142: [Usaco2017 Dec]Haybale Feast Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 182  Solved: 131[ ...

  2. 【BZOJ4552】排序(线段树,二分答案)

    [BZOJ4552]排序(线段树,二分答案) 题面 BZOJ 题解 好神的题啊 直接排序我们做不到 怎么维护? 考虑一下,如果我们随便假设一个答案 怎么检验它是否成立? 把这个数设成\(1\),其他的 ...

  3. BZOJ4552 HEOI/TJOI2016 排序 线段树、二分答案

    题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=4552 题意:给出一个$1$到$N$的全排列,对其进行$M$次排序,每次排序将区间$[l ...

  4. LOJ 2585 「APIO2018」新家 ——线段树分治+二分答案

    题目:https://loj.ac/problem/2585 算答案的时候要二分! 这样的话,就是对于询问位置 x ,二分出一个最小的 mid 使得 [ x-mid , x+mid ] 里包含所有种类 ...

  5. luoguP6619 [省选联考 2020 A/B 卷]冰火战士(线段树,二分)

    luoguP6619 [省选联考 2020 A/B 卷]冰火战士(线段树,二分) Luogu 题外话1: LN四个人切D1T2却只有三个人切D1T1 很神必 我是傻逼. 题外话2: 1e6的数据直接i ...

  6. 【BZOJ4094】[Usaco2013 Dec]Optimal Milking 线段树

    [BZOJ4094][Usaco2013 Dec]Optimal Milking Description Farmer John最近购买了N(1 <= N <= 40000)台挤奶机,编号 ...

  7. BZOJ4756: [Usaco2017 Jan]Promotion Counting(线段树合并)

    题意 题目链接 Sol 线段树合并板子题 #include<bits/stdc++.h> using namespace std; const int MAXN = 400000, SS ...

  8. BZOJ[Usaco2017 Jan]Promotion Counting——线段树合并

    题目描述 The cows have once again tried to form a startup company, failing to remember from past experie ...

  9. BZOJ4391 High Card Low Card [Usaco2015 dec](贪心+线段树/set库

    正解:贪心+线段树/set库 解题报告: 算辣直接甩链接qwq 恩这题就贪心?从前往后从后往前各推一次然后找一遍哪个地方最大就欧克了,正确性很容易证明 (这里有个,很妙的想法,就是,从后往前推从前往后 ...

随机推荐

  1. Redis具体解释与常见问题解决方式

    Redis简单介绍 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对很多其它.包含string(字符串).list(链表).set(集合).zset ...

  2. linux mysql 统一字符编码

    强调:配置文件中的注释可以有中文,但是配置项中不能出现中文 mysql> show variables like '%char%'; +--------------------------+-- ...

  3. mysql 内置功能 存储过程 目录

    mysql 内置功能 存储过程介绍 mysql 内置功能 存储过程 创建无参存储过程 mysql 内置功能 存储过程 创建有参存储过程 mysql 内置功能 存储过程 删除存储过程

  4. Spring boot Security 用于权限管理,用户添加等。

    1:添加依赖: <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thy ...

  5. 顺序结构,判断结构 if,switch

    1:顺序结构:从上往下执行程序代码,为顺序结构 ---------------------------------------------------------------------- 2:判断结 ...

  6. spring的统一异常处理

    在控制器(controller)中添加统一异常处理的方法,在方法前面加@ExceptionHandler[(异常类.class)]注解

  7. siblings()

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. unity3d-射线(Ray)

    射线Ray 射线是一个点向另外一个点发生的一条线,一旦与其他模型发生碰撞,他将停止发射.注意这条件是逻辑上的,界面上看不到. 一般使用射线判断是否发射至某个游戏对象上或者获得鼠标点击的游戏对象等. 用 ...

  9. html02

    复习:HTML标记 p h1~h6 font table>tr>td ul>li ol>li div span form:input>typy :password rad ...

  10. mysql外键使用和事物使用

    mysql外键功能主要是为了保证关联表数据的一致性,主要目的是控制存储在外键表中的数据. 使两张表形成关联,外键只能引用外表中的列的值! 例如: a b 两个表 a表中存有 客户号,客户名称 b表中存 ...