zoukankan      html  css  js  c++  java
  • poj3685 二分套二分

    F - 二分二分

    Crawling in process... Crawling failed Time Limit:6000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu

    Submit Status

    Description

    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
    题目大意:给你一个n*n矩阵,每一个位置都有一个值,这个值由该点的该点的行列标决定,问你第m小的元素是多少。
    思路分析:比赛时都贴上二分标签了,最后还没敲出来,首次我们要二分答案,然后check,check函数里面按列
    进行枚举,因为在j确定的情况下函数关于i递增,然后直接二分查找刚好小于等于mid的元素在每一列的位置,累加
    return,判断返回的数与m的关系,继续二分
    代码:
    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    using namespace std;
    const int inf=1e9;
    typedef long long ll;
    const int  C=100000;
    ll f(ll x,ll y)
    {
        return (x*x+C*x+y*y-C*y+x*y);
    }
    ll n,m;
    ll checknum(ll num)
    {
        ll cnt=0;
         for(int i=1;i<=n;i++)//枚举列,因为在列数确定的情况下表达式关于i是递增的
         {
                ll sl=1,sr=n;
                int ant=0;
                while(sl<=sr)
                {
                    ll smid=(sl+sr)>>1;
                    if(f(smid,i)<=num)
                    {
                        ant=smid;
                        sl=smid+1;
                    }
                    else sr=smid-1;
                }
                cnt+=ant;
        }
        return cnt;
    }
    int main()
    {
       int T;
       scanf("%d",&T);
       while(T--)
       {
           scanf("%lld%lld",&n,&m);
           ll l=-100000*n,r=n*n+100000*n+n*n+n*n;
           ll ans;
           while(l<=r)
           {
               ll mid=(l+r)>>1;
                //cout<<mid<<endl;
               if(checknum(mid)>=m)
               {
                   ans=mid;
                   //cout<<ans<<endl;
                   r=mid-1;
               }
               else l=mid+1;
              // cout<<ans<<endl;
           }
           printf("%lld
    ",ans);
       }
    }
  • 相关阅读:
    scrapy爬虫系列之三--爬取图片保存到本地
    scrapy爬虫系列之四--爬取列表和详情
    python3.7.2 ssl版本过低导致pip无法使用的问题
    python3安装后无法使用退格键的问题
    位运算符和unity Layers
    unity常用小知识点
    unity -- Time类(持续更新中)
    随便说说 post-processing
    unity图片后期处理
    顶点/片元 shader 总结
  • 原文地址:https://www.cnblogs.com/xuejianye/p/5691120.html
Copyright © 2011-2022 走看看