zoukankan      html  css  js  c++  java
  • POJ 3685 二分套二分

    Given a N × N matrix A, whose element in the i-th row and j-th column Aij is an number that equals i2 + 100000 × i + j2 - 100000 × j + i × j, you are to find the M-th smallest element in the matrix.

    Input

    The first line of input is the number of test case.
    For each test case there is only one line contains two integers, N(1 ≤ N ≤ 50,000) and M(1 ≤ MN × N). There is a blank line before each test case.

    Output

    For each test case output the answer on a single line.

    Sample Input

    12
    
    1 1
    
    2 1
    
    2 2
    
    2 3
    
    2 4
    
    3 1
    
    3 2
    
    3 8
    
    3 9
    
    5 1
    
    5 25
    
    5 10
    

    Sample Output

    3
    -99993
    3
    12
    100007
    -199987
    -99993
    100019
    200013
    -399969
    400031
    -99939
    

    刚看到题的时候依旧一脸懵逼,不知道从哪开始下手,还是向大佬的题解妥协了

    式子是关于i单调递增的(求偏导……都会得……嗯……)然后,找突破口

    先二分答案x,然后二分的去找每行<x的个数,根据小于x的个数来调整x的大小。。。——二分套二分……

    #include<iostream>
    #include<stdio.h>
    #include<cmath>
    #include<string.h>
    #include<algorithm>
    typedef long long ll;
    using namespace std;
    ll n, m,t;
    bool judge(ll a, ll b,ll c)
    {
        return (a*a + 100000*a + b*b - 100000*b + a*b)<c;
    }
    bool C(ll x)
    {
        ll crt = 0;
        for (int i = 1; i <= n; i++)  //i从1开始
        {
            ll le = 0, r = n + 1;
            while (le<r-1)  //找没行多少个小于mid的
            {
                ll mi = (r + le) /2 ;
                if (judge(mi, i, x)) le = mi;
                else r = mi;
            }
            crt += le;  
        }
        return crt < m;
    }
    int main()
    {
           scanf("%lld", &t);
            while (t--)
            {
                scanf("%lld%lld",&n, &m);
                ll l = -100000*n, h = 3*n*n+100000*n;  
                while(h-l>1)
                {
                    ll mid = (h + l) / 2;
                    if (C(mid)) l = mid;
                    else h = mid;
                }
                printf("%lld
    ", l);
            }
        return 0;
    }
  • 相关阅读:
    20210815 图论模拟赛
    20210813 杂项の模拟赛
    20210812dp模拟赛
    20210811数据结构
    html问题记录20180514
    Oracle导出表空间的创建语句、导入、导出dmp文件
    浮动子div撑开父div的几种方法、给select赋值、zoom样式的含义、实现select下拉框readonly
    Fidder教程
    JQuery插件的写法和规范
    box-sizing position calc() @media
  • 原文地址:https://www.cnblogs.com/Egoist-/p/7406839.html
Copyright © 2011-2022 走看看