CodeForces - 448D—Multiplication Table--二分法(nlogn)

来源:互联网 发布:零境网络 官网 编辑:程序博客网 时间:2024/06/06 04:16

Description

Bizon the Champion isn't just charming, he also is very smart.

While some of us were learning the multiplication table, Bizon the Champion had fun in his own manner. Bizon the Champion painted an n × m multiplication table, where the element on the intersection of the i-th row and j-th column equals i·j (the rows and columns of the table are numbered starting from 1). Then he was asked: what number in the table is the k-th largest number? Bizon the Champion always answered correctly and immediately. Can you repeat his success?

Consider the given multiplication table. If you write out all n·m numbers from the table in the non-decreasing order, then the k-th number you write out is called the k-th largest number.

Input

The single line contains integers nm and k(1 ≤ n, m ≤ 5·105; 1 ≤ k ≤ n·m).

Output

Print the k-th largest number in a n × m multiplication table.

Sample Input

Input
2 2 2
Output
2
Input
2 3 4
Output
3
Input
1 10 5
Output
5

Hint

2 × 3 multiplication table looks like this:

1 2 32 4 6

题意::n行m列的矩阵,第 i 行 j 列的值为 i*j ,这n*m个数按照非递减数列排列起来,问第k个数是什么。

思路::如果用sort肯定要超时。但我们发现矩阵的每一行都是按照非递减数列排列的,符合二分法的性质。我们假设mid为第k个数。我们通过求出在每一行中mid为第几个数,然后把他们加起来与k进行比较,如果大于k那么就要减小mid,否则增大mid。

代码::

#include <iostream>#include <sstream>#include <ios>#include <iomanip>#include <functional>#include <algorithm>#include <vector>#include <string>#include <list>#include <queue>#include <deque>#include <stack>#include <set>#include <map>#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <climits>#include <cctype>using namespace std;#define XINF INT_MAX#define INF 0x3FFFFFFF#define MP(X,Y) make_pair(X,Y)#define PB(X) push_back(X)#define REP(X,N) for(int X=0;X<N;X++)#define REP2(X,L,R) for(int X=L;X<=R;X++)#define DEP(X,R,L) for(int X=R;X>=L;X--)#define CLR(A,X) memset(A,X,sizeof(A))#define IT iteratortypedef long long ll;typedef pair<int,int> PII;typedef vector<PII> VII;typedef vector<int> VI;//const int MAXN = 10010;//#define INF 0x3FFFFFFF/***************************************************头文件*******************************************************/ll n,m,k;int main(){while(cin>>n>>m>>k){ll l = 1,r = m*n, mid;//左右中while(l!=r){mid = (l+r)/2;ll tot = 0;//记录mid的位置REP2(i,1,n){    ll x = mid/i;tot += (x<=m)?(x):m;//mid在每一行中的位置不会大于最大的列数}if(tot<k)l = mid+1;            else r = mid;}cout<<l<<endl;}return 0;}











2 0