首页 > 其他分享 >hdu:第K小的数(构造二分)

hdu:第K小的数(构造二分)

时间:2023-05-26 23:45:07浏览次数:48  
标签:二分 dots hdu 正整数 int ll mid 构造 leq

Problem Description
给定\(n\)个正整数\(a_1,a_2,\dots,a_n\)和\(m\)个正整数\(b_1,b_2,\dots,b_m\)。

请在\(n\times m\)个\(a_i + b_j(1\leq i\leq n,1\leq j\leq m)\)中,找到第\(k\)小的数(不去重)。

Input
第一行包含一个正整数\(T(1\leq T\leq 10)\),表示测试数据的组数。

每组数据第一行包含三个正整数\(n,m,k(1\leq n,m\leq 100000,1\leq k\leq n\times m)\)。

第二行包含\(n\)个正整数\(a_1,a_2,\dots,a_n(1\leq a_i\leq 10^8)\)。

第三行包含\(m\)个正整数\(b_1,b_2,\dots,b_n(1\leq b_i\leq 10^8)\)。

输入样例
1
3 4 7
5 4 3
7 6 8 6

输出样例
11

数学--构造二分

典型题,首先将a和b分别排序,第k值一定在a[1]+b[1]和a[n]+b[m]之间,二分区间求最小的x使得f(x)>=x,f(x)表示所生成数中小于等于x的数量。求f(x)的方法使用双指针

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int n,m;
ll k;
int a[N],b[N];

ll f(ll x)
{
	int j=m;
	ll cnt=0;
	for(int i=1;i<=n;++i)
	{
		while(j&&(ll)a[i]+b[j]>x) j--;
		cnt+=j;
	}
	return cnt;
}

ll bina(ll mi,ll ma)
{
	ll l=mi,r=ma,ans=r;
	while(l<=r)
	{
		ll mid=(l+r)>>1;
		ll tmp=f(mid);
		if(tmp>=k) ans=mid,r=mid-1;
		else l=mid+1;
	}
	return ans;
}

void solve()
{
    cin>>n>>m>>k;
    for(int i=1;i<=n;++i) cin>>a[i];
    for(int i=1;i<=m;++i) cin>>b[i];
    sort(a+1,a+1+n);
    sort(b+1,b+1+m);
    cout<<bina((ll)a[1]+b[1],(ll)a[n]+b[m])<<'\n';//注意此处的换行
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int T;
    cin>>T;
    while(T--)
    {
        solve();
    }
    return 0;
}

标签:二分,dots,hdu,正整数,int,ll,mid,构造,leq
From: https://www.cnblogs.com/ruoye123456/p/17436077.html

相关文章

  • 什么是构造函数?它有什么作用?
    构造函数是一个特殊的方法,它用于创建对象时初始化对象的实例变量。每个类都至少有一个构造函数,如果没有定义,则会有一个默认的无参构造函数。构造函数与类名相同,没有返回类型。构造函数可以用于为对象分配内存,初始化对象的状态,执行其他初始化任务等。......
  • C++类的基础、构造、析构
    双向链表节点——具体的表表里面要维护什么是由你自己来决定的以链表为例讲解为什么需要类用户修改了你的链表,暴露给所有人创建和销毁,忘记了,内存泄漏冗长的名字封装分离实现细节和接口一定要把细节private接口public接口修改调用我们是知道的......
  • hdu:Ice Cream Tower(构造二分)
    一座高度为k的塔\(b1,b_2,\dots,b_k\)满足\(2b_1\leqb_2,2b_2\leqb_3,2b_3\leqb_4,\dots,2b{k-1}\leqb_k\)你要从中选择一些数来叠很多座高度为\(k\)的塔,问最多能叠多少座塔。Input第一行包含一个正整数T(1≤T≤10),表示测试数据的组数。每组数据第一行包含两个正整数n,k(2......
  • hdu:序列划分(构造二分)
    ProblemDescription给定\(n\)个正整数\(a_1,a_2,\dots,a_n\),将这个序列从左到右划分成\(m\)段,使得每段至少有一个数。你需要让数字之和最大的那一段的数字和尽可能得小。Input第一行包含一个正整数T(1≤T≤10),表示测试数据的组数。每组数据第一行包含两个正整数n,m(1≤m≤......
  • matlab 构造逐渐震荡衰减的函数
    t=0:0.01:10;%时间范围freq=5;%振荡频率amp=1;%初始振幅duration=5;%振荡持续时间decay_rate=0.1;%衰减速率y=amp*sin(2*pi*freq*t).*exp(-decay_rate*t);%构造函数plot(t,y);%绘制图形xlabel('时间');ylabel('振幅');title('逐渐震荡衰减函数');......
  • HDU 1176 免费馅饼(简单动态规划)
    传送门这道题是中文描述的,我相信大家都肯定能够看得懂(滑稽),思路上呢大概就是一个升级版的数塔(点我去看数塔)既然是动态规划问题所以首先肯定要先找出来状态转移方程,我找到的状态转移方程就是a[i][j]+=max(max(a[i+1][j+1],a[i+1][j]),a[i+1][j-1]),其中a[i][j]就是表示第i时刻在k位......
  • HDU 1029 Ignatius and the Princess IV(基础dp)
    传送门题目大意就是给你n个数(保证n为一个奇数),存在一个数出现的次数大于(n+1)/2次,求这个数;这个数出现的次数比其他数出现的次数加起来还多,那么当这个数出现时+1,其他的数出现时-1,最后得到的数为正数。假定一个数为特殊数,若当前数与特殊数相同则cnt++,若不相同则cnt--,如果这时cnt<0,用当......
  • HDU 2084 数塔(动态规划入门)
    传送门中文题就不给大家翻译了(手动滑稽),反正大家都看得懂。这是一道动态规划入门的题目,只需要找出状态转移方程即可。状态方程:dp[i][j]=a[i][j]+max(dp[i+1][j],dp[i+1][j])(dp[i][j]表示从第i层第j个数开始搜能得到的最大数)代码如下:#include<cstring>#include<iostream>#include<......
  • HDU 1024 Max Sum Plus Plus(动态规划)
    传送门题意是给你个数字序列,现在让你把这个序列分成m个连续的子序列,且要求这m个子序列的累加和最大。思路:这道题的题意可以理解为问在序列为末尾时,把序列分为m个子序列这个状态时的最大累加和,那么可以得出这个状态应该是由上一个状态转移得来:(因为dp[i][j]表示数到第j个字符时,前j个......
  • 软件构造课程思考10
    11面向可复用性和可维护性的设计模式创建模式:工厂方法结构模式适配器模式:具有不兼容接口的类可以通过将其自己的接口包装在现有类的接口周围来协同工作装饰器模式行为模式:策略模式:允许在运行时选择一系列算法中的一个模板模式:规定抽象逻辑,实现细节需要实现迭代器模式:顺序访问......