题目链接
题目大意
现在给你一个n×m的矩阵,已知矩阵的第x行第y列的元素为 axx+bx+cy,求第k大的元素值。
题目思路
二分第 k 大的数,每次 check 有几个数比它小的数,细节有点麻烦注意long long 以及1ll的使用
其实我觉得题目想到二分应该应该不算难,因为发现行列是1e5,那么复杂度正常来说应该是n*logn,而logn的话根据所学知识以及题目肯定是二分,但当时没想到,这题还是有点意思的
long long 为 9e18
代码
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
int n,m;
int a,b,c;
ll x[maxn],k;//注意k是ll
bool check(ll zhi){
ll sum=0;
if(c>0){
for(int i=1;i<=n;i++){
if(zhi>=x[i]){
if((zhi-x[i])/c+1>=m){
sum+=m;
}else{
sum+=(zhi-x[i])/c+1;
}
}
}
}else if(c<0){
for(int i=1;i<=n;i++){
if(zhi>=x[i]+1ll*c*(m-1)){//有乘号就要注意1ll ,还有最后一列的值为x[i]+1ll*c*(m-1)
if((zhi-x[i]-1ll*c*(m-1))/(-c)+1>=m){//注意是除以-c
sum+=m;
}else{
sum+=(zhi-x[i]-1ll*c*(m-1))/(-c)+1;
}
}
}
}else{
for(int i=1;i<=n;i++){
if(zhi>=x[i]){
sum+=m;
}
}
}
return sum+k-1>=1ll*n*m;//这个式子注意
}
signed main(){
scanf("%d %d %lld %d %d %d",&n,&m,&k,&a,&b,&c);
for(int i=1;i<=n;i++){//每行第一个元素的值
x[i]=1ll*a*i*i+1ll*b*i+c;
}
ll l=-1e18,r=1e18,ans=1e18;
while(l<=r){
ll mid=l+(r-l)/2;
if(check(mid)){//大于或等于第k大的数
ans=min(ans,mid);
r=mid-1;
}else{
l=mid+1;
}
}
printf("%lld\n",ans);
return 0;
}