题目
题解
当时看题的时候很懵B,因为我把第k小看成第k大。
问第k小的,且K≤max(N,M),画一下图就知道1…x的个数为S=Σ⌊xi⌋.
所以显然可以二分求出S,与k进行比较来二分。
发现有很多相同的⌊xi⌋。所以经典分块解决问题。
如何分块:设⌊xi⌋,i∈[l,r]这些⌊xi⌋都相同。那么已知x是r的倍数,所以
∀i∈[l,r],⌊x⌊xi⌋⌋=r
r+1就是下一块的左端点。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define LL long long
#define P(a) putchar(a)
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
LL i,j,k,l,r,l1,r1,mid,sum,ans;
LL n,m,q,x;
int main(){
scanf("%lld%lld%lld",&n,&m,&q);
if(m>n)swap(n,m);
while(q--){
scanf("%lld",&k);
l=1,ans=r=k;
while(l<r){
sum=0;
mid=(l+r)/2;
i=1;
while(i<m){
if(i>mid || sum>=k)break;
l1=i;
r1=mid/(mid/i)+1;
sum+=(mid/i)*(r1-l1);
i=r1;
}
if(sum<k)l=mid+1;else ans=mid,r=mid;
}
printf("%lld\n",ans);
}
return 0;
}