poj3685(二分查找第k小)

来源:互联网 发布:java占用cpu过高 编辑:程序博客网 时间:2024/05/16 03:04
/*translation:给出一个矩阵,其中每项的值为:i*i + C*i + j*j - C*j + i*j;(i,j分别为所在的行和列)。求其第m小的数字solution:二分查找k小数字观察发现矩阵的规律是从上倒下递增,从左到右递减。可以根据这个规律来二分查找有几个小于当前给出的值。详见代码note:date:2016.11.5*/#include <iostream>#include <cstdio>using namespace std;const int maxn = 50000 +5;const int C = 1e5;typedef long long ll;ll n, m;ll f(ll i, ll j){return i*i + C*i + j*j - C*j + i*j;}bool check(ll mid){ll cnt = 0;for(ll j = 1; j <= n; j++){//对这一列小于等于mid的计数ll lb = 0, ub = n + 1;while(ub - lb > 1){ll i = (lb + ub) >> 1;if(f(i, j) >= mid)ub = i;elselb = i;}cnt += lb;}return cnt >= m;}int main(){//freopen("in.txt", "r", stdin);int T;scanf("%d", &T);    while(T--){cin >> n >> m;ll lb = -C*n, ub = 3*n*n + 100000*n;while(ub - lb > 1){ll mid = (ub + lb) >> 1;if(check(mid))ub = mid;elselb = mid;}printf("%lld\n", lb);    }    return 0;}

0 0
原创粉丝点击