(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦
题目:传送门
(原题目描述及样例在最下面。)
题意很简单,给两个长度为n(5e4)的序列a,b。问新序列c中第k大的元素。
新序列c就是a和b中两两相加得出的序列。
思路:
把a和b序列排序后,二分。
二分上界为a[n-1]+b[n-1],二分下界为a[0]+b[0]。
注意爆int了。要用longlong。
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long LL;
const int N = 50000+5;
int n;
LL k;
int ar[N],br[N];
LL num(int m){
LL cnt=0;
for(int i=0;i<n;++i){
int p=upper_bound(ar,ar+n,m-br[i])-ar;
cnt+=p;
}
return cnt;
}
int main(){
while(~scanf("%d%lld",&n,&k)){
for(int i=0;i<n;++i){
scanf("%d",&ar[i]);
}
for(int i=0;i<n;++i){
scanf("%d",&br[i]);
}
sort(ar,ar+n);sort(br,br+n);
int l=ar[0]+br[0],r=ar[n-1]+br[n-1],m,ans;
while(l<=r){
m=(l+r)>>1;
if(num(m)>=k){
r=m-1;
ans=m;
}else{
l=m+1;
ans=m+1;
}
}//5 6 6 7 7 7 8 8 9
printf("%d\n",ans );
}
return 0;
}
题目描述:
Description
给出两个长度均为n的数组A、B。而C数组是A和B合成的,长度为n*n,并且满足等式c[(j-1)*n+k]= a[j]+b[k] (1<=j、k<=n)
其实就是说C中的元素分别是A[1]+B[1]、A[1]+B[2]、……、A[1]+B[n]、A[2]+B[1]、……、A[2]+B[n]、……、A[n]+B[n]
求C中第K大的元素的值(从小到大排序后的第k个)
Input
输入包括不超过15组数据
第一行有两个数,分别为A、B的长度n以及k(1<=n<=50000,1<=k<=min(n*n,1000000000))
第二行n个值为数组A (1<=A[i]<=50000)
第三行n个值为数组B (0<=B[i]<=50000)
Output
输出一行,为C数组中第K大的数
Sample Input
3 4
1 2 3
4 5 6
Sample Output
7
Hint
Source
中南大学2017年5月月赛
Author
卢铭威
CF981D:
把n个数字分成k段,每一段的值等于那一段所有数字之和,问k段数字逻辑和最大是多少?
思路:
因为逻辑和最大不超过long long,我们就从高到低枚举每一位为1的情况。
判断是否可以可行的过程,用dp[i][j]=1或0表示前i个数字为分成j段,逻辑和能否为x。
if(sum[i]&x==x)dp[i][1]=1;
if((sum[i]-sum[j])&x==x)dp[i][h]|=dp[j][h-1]
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 55;
const int INF = 0x3f3f3f3f;
int n,k;
LL sum[N],d[N][N];
LL check(LL x){
memset(d,0,sizeof(d));
for(int i=1;i<=n;++i){
if((sum[i]&x)==x){
d[i][1]=1;
}
for(int j=1;j<i;++j){
if(((sum[i]-sum[j])&x)!=x)continue;
for(int h=2;h<=min(k,i);++h){
d[i][h]|=d[j][h-1];
}
}
}
return d[n][k];
}
int main(){
while(~scanf("%d%d",&n,&k)){
sum[0]=0;
for(int i=1;i<=n;++i){
scanf("%lld",&sum[i]);
sum[i]+=sum[i-1];
}
LL ans=0;
for(int i=60;i>=0;--i){
if(check(ans|(1LL<<i))){
ans|=(1LL<<i);
}
}
printf("%lld\n",ans );
}
return 0;
}