• 1777:寻找整数


    1777:寻找整数

    时间限制: 1000 ms         内存限制: 262144 KB
    【题目描述】

    给定整数m,k,求出正整数n使得n+1,n+2,…,2n 中恰好有m个数在二进制下恰好有k个1。有多组数据。
    【输入】

    第一行一个整数 t表示数据组数。接下来 t 行每行两个整数m,k。
    【输出】

    每组数据输出一行两个整数,第一个数表示264-1范围内任意一个满足条件的 n,第二个数表示满足条件的 n 的个数(无穷多用-1表示)。保证1018以内存在满足条件的 n。

    如果每组数据第一个数全部正确,得4分。

    如果每组数据第二个数全部正确,得6分。

    【输入样例】

    1
    1 2

    【输出样例】

    2 1

    【提示】

    【数据规模】

    对于10%的数据,k=2。

    对于20%的数据,k≤3。

    对于另外50%的数据,保证满足条件的 n均在1018以内。

    对于100%的数据,t≤2000,0≤m≤1018,1≤k≤64。

    【题解】

    发现题目所求等于1有k的个数的数随着n增加单调递增,所以答案一定在一个区间内。

    我们就可以二分出区间的上下界,现在问题就是如何求出区间内1等于k的数的个数。

    按照常规差分成1-n-1,1-2n。

    对于一个x,强制其每一位为1的位为0,前头为1的位都为1,后头有好多种方法,用组合数求解。

    代码如下:

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int inf=2e18+5;
    int t,m,k,f[75][75],C[74][75];
    inline int solve(int x)
    {
        int i,j=0,daan=0;
        x++;
        for(int i=62;i>=0;i--)
        {
            if(x&(1ll<<i))
            {
                if(k>=j) daan+=C[i][k-j];
                j++;
            }
        }
        return daan;
    }
    inline int check(int x)
    {
        return solve(2ll*x)-solve(x);
    }
    inline int find()
    {
        int l=1,r=inf,daan;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(check(mid)<m) l=mid+1;
            else r=mid-1,daan=mid;
        }
        return daan;
    }
    signed main()
    {
        cin>>t;
        for(int i=0;i<=70;i++) C[i][0]=1;
        for(int i=1;i<=70;i++) for(int j=1;j<=i;j++) C[i][j]=C[i-1][j-1]+C[i-1][j];
        while(t--)
        {
            cin>>m>>k;
            if(m==0)
            {
                cout<<"1 "<<(1ll<<k-1)-1<<"
    ";
                continue;
            }
            if(k==1&&m==1)
            {
                cout<<"1 -1
    ";
                continue; 
            }
            int hu1=find();
            m++;
            int hu2=find();
            cout<<hu1<<" "<<hu2-hu1<<"
    ";
        }
    }
    View Code
  • 相关阅读:
    求素数(定义法,埃式法,欧拉法)
    打表法
    python学习日记(匿名函数)
    python学习日记(编码再回顾)
    python学习日记(文件操作练习题)
    python学习日记(迭代器、生成器)-乱七八糟
    python学习日记(生成器函数进阶)
    python学习日记(装饰器的补充)
    python学习日记(函数--装饰器)
    python学习日记(函数进阶)
  • 原文地址:https://www.cnblogs.com/betablewaloot/p/12247293.html
Copyright © 2020-2023  润新知