首页 > 其他分享 >二分 & 三分

二分 & 三分

时间:2024-10-31 16:48:05浏览次数:4  
标签:二分 int sum m1 ans 三分

二分查找

多用于dp优化

源码

//自己写的时候推荐把边界放宽一点
while(r-l>1) {	//最后一个小于k的位置
	int mid=l+r>>1;
	if(a[mid]<x) l=mid;
	else r=mid-1;
}
if(a[r]<x) l=r;

STL库函数

注意以下返回的都是指针

#include<algorithm>
upper_bound(a+1,a+n+1,k)		//第一个大于k的位置
lower_bound(a+1,a+n+1,k)		//第一个大于等于k的位置
bool cmp(int x,int k) {			//自定义规则,注意k是给定参数,不是a[]的元素
	return val[x]<=val[k];
}
lower_bound(a+1,a+n+1,k,cmp)		//第一个不符合cmp的位置
upper_bound(a+1,a+n+1,k,cmp)		//最后一个符合cmp的位置

细节处理

给定不降序列\(\{a_n\}\),数 \(x\) ,求:

1、小于\(x\)的最大值的位置

边界:\(a[l]<x,a[r]<x,r-l=1\)

二分答案

01分数规划

\(\color{red} {^*}\)核心:抽象出 \({\sum s_i}-ans*{\sum p_i}=0\) ,求最大值则判大于0,求最小值则判小于0

模型

有一些二元组 \((s_i,p_i)\),从中选取一些二元组,使得\(\frac {\sum s_i}{\sum p_i}\)最大。

设 \(\frac {\sum s_i}{\sum p_i}=ans\),则 \({\sum s_i}-ans*{\sum p_i}=0\) (核心公式)

即 \(\sum{(s_i-ans*p_i)}=0\)

二分 \(ans\) ,将每个二元组赋权值 \(s_i-ans*p_i\) ,贪心找大于0的数。

若存在最优答案>=0,则当前二分值偏小。否则,说明偏大。

p.s. 也有除数为连续区间长的,即 \(p_i=1\) 且不能跳选,赋值 \(s_i-ans\) 求最大子段和即可。

例题

例1:[P3199] 输出平均值最小的环的平均值

n<=3000,m<=10000

例2:有带权图G, 对于图中每条边\(e[i]\), 都有\(benifit[i]\)(收入)和\(cost[i]\)(花费), 我们要求的是一棵生成树T, 它使得 \(∑(cost[i]) / ∑(benifit[i]), i∈T\) 最小.

P3778 [APIO2017] 商旅

先是分数规划,\(\sum w-ans*t\le0\)

该环可以分成根据包里的物品分成若干段,分段考虑,对于段\(i\to j\),最大权为\(max_{l=1}^k\{s[j][l]-b[i][l]\}-ans*dis[i][j]\),预处理后,floyd跑最大环即可

p.s. 想要分层图+SPFA的我像个sb

p.s.s. 这题卡精度,有个答案是\(0.999999998\),要开\(long\ double,eps=10^{-9}\)才能过

整体二分

三分

细节说明

边界

对于整数下标的三分,可能出现\(m_1=l\text{或}\ m_2=r\)的情况,此时$\ [l,r]\ $较小,可以直接枚举。

	int l=1,r=MAXN;
	while(true) {
		int m1=l+(r-l)/3,m2=r-(r-l)/3;
		if(l==m1||r==m2) break;
		if(Check(m1)<Check(m2)) r=m2;
		else l=m1;
     	}	
  	ans=Check(l);
	for(int i=l+1;i<=r;i++)	ans=min(ans,Check(i));

不适用情况

答案符合单峰函数,但是变化幅度过小(尤其是整数三分),使得Check(m1)==Check(m2),不知道转移方向 (整数三分事真多

解决方法

1、一定条件下转换成二分来用

2、去重(不是枚举去重,是找贡献点,因为变化幅度小的贡献点很少)

例:[P1314] 上述两种都适用

[P6619] 构成单峰的是两段单调的曲线,考虑它们分别产生贡献的两段,分别二分找答案即可

P3745 [六省联考 2017] 期末考试

E. 延误列车

首先放到\(x-t\)图上,即为若干个抛物线

题意即为求一个时刻\(t_0\),使得所有抛物线以与\(t=t_0\)的直线的交点为顶点时,都会走到\(x=d\)处

即求一个\(d\)使得上凸函数\(f_i(t)\ge d\),下凸函数\(f_j(t)\le d\)

即为\(\min(f_i(t))\ge d\)且\(\max(f_j(t))\le d\)

两式相减得\(\min(f_i(t))-\max(f_j(t))\ge 0\)

令\(g(t)=\min(f_i(t))-\max(f_j(t))\)可以证明上凸,用三分求出

标签:二分,int,sum,m1,ans,三分
From: https://www.cnblogs.com/zhone-lb/p/18518311

相关文章

  • 【优选算法】——二分查找!
    目录1、二分查找2、在排序数组中查找元素的第一个和最后一个位置3、搜索插入位置4、x的平方根5、山脉数组的封顶索引6、寻找峰值 7、寻找旋转排序数组中的最小值8、点名9、完结散花1、二分查找给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 targ......
  • 网络流&费用流&二分图
    NOIP也许考不到,但是可以拿来骗分也说不定(算法原理就算了,反正也不需要知道,只需要知道它在干什么并且会建图就行了。二分图就是左右两部点,同一部内的点无连边,可以考虑建二分图后网络流。持续放些题。一些基本理论和建模方式最小割=最大流最大权闭合子图切糕模型二......
  • 二分类结果评估指标
    TP(TruePositive):真正例,真值和预测值都是正例FP(FalsePositive):假正例,真值是负例,预测值是正例FN(FalseNegative):假负例,真值是正例,预测值是负例TN(TrueNegative):真负例,真值和预测值都是负例Accuracy(准确率):对于给定的测试数据集,分类器正确分类的样本数与总样本数之比。P......
  • CSP/信奥赛C++刷题训练:经典二分例题(2):洛谷P1678:烦恼的高考志愿
    CSP/信奥赛C++刷题训练:经典二分例题(2)烦恼的高考志愿题目背景计算机竞赛小组的神牛V神终于结束了高考,然而作为班长的他还不能闲下来,班主任老t给了他一个艰巨的任务:帮同学找出最合理的大学填报方案。可是v神太忙了,身后还有一群小姑娘等着和他约会,于是他想到了同为计......
  • 提高:二分与三分:扩散
    一个点每过一个单位时间就会向四个方向扩散一个距离,如图。两个点a、b连通,记作e(a,b)当且仅当a、b的扩散区域有公共部分。连通块的定义是块内的任意两个点u、v都必定存在路径e(u,a0),e(a0,a1),…,e(ak,v)。给定平面上的n给点,问最早什么时刻它们形成一个连通块。输入第一行一......
  • 二分算法
    1.二分查找个人习惯使用左闭右闭的方法,不管用来求位置、求最大还是最小,都是同一个写法intfindborder(vector<int>&nums,inttgt){ intleft=0,right=nums.size();while(left<=right){intmid=left+(right-left)/2; //防溢出写法......
  • 初识算法 · 二分查找(4)
    目录前言:寻找峰值题目解析算法原理算法编写寻找旋转排序数组中的最小值题目解析算法原理算法编写寻找缺失的数字题目解析算法原理算法编写前言:​本文的主题是二分查找,通过三道题目讲解,一道是寻找峰值,一道是搜索旋转排序数组的最小值,一道是0-n-1中缺失的数字......
  • 求中位数应经常联想到二分
    题目链接:https://codeforces.com/contest/2008/problem/H首先想了一会,随后想到了取模,但是由于这个q太大于是考虑是否可以实现动态变化最后还是没得出结果,遂看了题解。原来这道题由于n的限制,所以可以对求出取模所对应的余数的取模区间\([k*x,k*x+m]\),于是复杂度到了\(nlogn\)(前......
  • E71 树形DP+二分 P3523 [POI2011] DYN-Dynamite
    视频链接:   P3523[POI2011]DYN-Dynamite-洛谷|计算机科学教育新生态//树形DP+二分O(nlogn)#include<iostream>#include<cstring>#include<algorithm>usingnamespacestd;intread(){intx=0,f=1;charc=getchar();while(c>'9'||c......
  • 二分图的判别(染色法、匈牙利算法)
    二分图的判别:首先二分图是指一个图如果没有奇数环,则该图是二分图。其实这两种算法都是基于dfs来做的,要深刻理解每个算法的dfs指代的是什么。1、染色法:所谓的染色是指所有边的每一条边的两个端点颜色不同,算法思路就是让每个顶点都做一次dfs,判断其中有无同一条边的端点颜色相同。......