[计蒜客]小 B 的题目
小 B 的题目
Description
小 B 给小 A 出了这样一道题:
给定一个长为 nn 的序列 AA 和一个长为 mm 的序列 BB,在 AA 和 BB 中各取一个数相加,可以得到 n\times mn×m 个数,他想知道把这些数从小到大排序,第 kk 个数是多少(下标从 11 开始)。
小 A 不会做,他想让你帮他解决这个问题。
Input
第一行三个整数 n,m,kn,m,k,表示 AA 和 BB 的长度以及小 A 想知道的是第 kk 小;
第二行 nn 个整数,第 ii 个数表示 A_iAi;
第三行 mm 个整数,第 ii 个数表示 B_iBi。
output
一行一个整数,表示答案。
对于前 10\%10% 的数据,保证 1\leq n,m\leq 1001≤n,m≤100;
对于前 20\%20% 的数据,保证 1\leq n,m\leq 2\times10^31≤n,m≤2×103;
对于另 20\%20% 的数据,保证 1\leq n,m \leq 2\times 10^51≤n,m≤2×105, 1 \le A_i, B_i \le 10001≤Ai,Bi≤1000;
对于另 30\%30% 的数据,保证 1\leq n,m \leq 2\times 10^5, 1\leq k \leq 2\times 10^51≤n,m≤2×105,1≤k≤2×105;
对于剩下 30\%30% 的数据,保证 1\leq n,m \leq 10^61≤n,m≤106, 1 \leq k \leq n \times m1≤k≤n×m, 1 \leq A_i,B_i \leq 10^91≤Ai,Bi≤109,这部分数据有一定梯度。
部分输入文件较大,请注意读入方式对效率的影响。
Examples
Input
2 3 5 2 2 1 3 2
Output
5
正确解法:
样例中的 2\times 32×3 个数从小到大排序后是 [3,3,4,4,5,5][3,3,4,4,5,5],其中第 55 个数是 55。
暴力得了10分。
正解是二分,从1-2e9开始找。
然后找mid 返回是否 大于 k个。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 #include <set> 7 #include <map> 8 #include <vector> 9 using namespace std; 10 typedef long long ll; 11 const int inf=0x7fffffff; 12 const int N=1000000+100; 13 int n,m; 14 ll k; 15 ll a[N],b[N]; 16 bool check(int x) 17 { 18 ll cnt=0; 19 for(int i=1,j=m;i<=n;i++) 20 { 21 while(a[i]+b[j]>x&&j>1) j--; 22 if(a[i]+b[j]<=x) cnt+=j; 23 } 24 if(cnt>=k) return 0; 25 return 1; 26 } 27 int main() 28 { 29 scanf("%d %d %lld",&n,&m,&k); 30 for(int i=1;i<=n;i++) 31 scanf("%d",&a[i]); 32 for(int i=1;i<=m;i++) 33 scanf("%d",&b[i]); 34 sort(a+1,a+n+1); 35 sort(b+1,b+m+1); 36 ll l=1,r=2e9; 37 while(l<=r) 38 { 39 ll mid=(l+r+1)/2; 40 if(check(mid)) l=mid+1; 41 else r=mid-1; 42 } 43 printf("%lld\n",l); 44 45 46 return 0; 47 }