I-Interesting Matrix Problem
题意:给你N *M的矩阵 (1<=N , M <=1e8)矩阵内的值是 i乘j 现有q次询问,每次询问输入k 代表 查询这个矩阵内第k小的数是多少。
做法:第一思路二分答案,然后mid去check O(N) 枚举行 i 计算mid/i的个数,发现会超时
写下公式:
这个公式好眼熟啊,不就是数论的整除分块,果断套了一个分块 时间复杂度:q*sqrt(N)
注意还要判断mid/i 不能大于m
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define per(i,a,b) for(int i=a;i>=(b);--i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair<int, int>
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
ll n,m,q,k;
int valid(ll mid)
{
ll ans=0;
ll l,r;
for(l=1;l<=mid;l=r+1){
r=mid/(mid/l);
ll t=mid/l;
t=min(t,m);
ans+=(1ll*r-l+1)*t;
}
return ans>=k;
}
void solve()
{
scanf("%lld%lld%lld",&n,&m,&q);
if(n>m) swap(n,m);
while(q--){
scanf("%lld",&k);
ll l=1,r=m,ans;
while(l<=r){
ll mid=l+r>>1;
if(valid(mid)) {
ans=mid,r=mid-1;
//printf("midmid:%lld\n",mid);
}
else l=mid+1;
}
printf("%lld\n",ans);
}
}
int main()
{
solve();
}
京公网安备 11010502036488号