版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/HuangXinyue1017/article/details/81407846
Time Limits: 1000 ms Memory Limits: 131072 KB
Description
Input
Output
Sample Input
3 5 3
1
3
5
Sample Output
1
2
3
Data Constraint
Solution
不难发现最优答案
我们二分答案 ,发现这个 在此矩阵中排序(从小到大)后的最右位置为
其实就是将小于等于 的数的个数相加,这个要是不知道为什么的画个图看一看就好了
但是这样的复杂度为 ,显然会超时80分,那就继续优化
观察发现,上式 中有很多值是相同的,而且是连续一段一段的,其值的数量又不超过
于是我们想到经典解法——分块
我们跳着一段一段加答案,每次 跳到 ,然后整个区间统计
时间复杂度
Code
#include<algorithm>
#include<cstdio>
#define ll long long
using namespace std;
int n,m,q,k;
bool ok(int x)
{
ll s=0;
for(int i=1,p;i<=min(n,x);i=p+1)
{
p=x/(x/i);
s+=(ll)(p-i+1)*(x/i);
}
return s>=k;
}
int main()
{
freopen("matrix.in","r",stdin);
freopen("matrix.out","w",stdout);
scanf("%d%d%d",&n,&m,&q);
while(q--)
{
scanf("%d",&k);
int l=1,r=k;
while(l<r)
{
int mid=(l+r)>>1;
if(ok(mid)) r=mid;
else l=mid+1;
}
printf("%d\n",l);
}
}