随笔- 181  文章- 2  评论- 0  阅读- 6750 

Problem Description
给定n个正整数a1,a2,,anm个正整数b1,b2,,bm

请在n×mai+bj(1in,1jm)中,找到第k小的数(不去重)。

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

每组数据第一行包含三个正整数n,m,k(1n,m100000,1kn×m)

第二行包含n个正整数a1,a2,,an(1ai108)

第三行包含m个正整数b1,b2,,bn(1bi108)

输入样例
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;
}

 posted on   ruoye123456  阅读(79)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示