给出BITS的总和找到thar数

时间:2014-02-13 16:28:21

标签: c++ algorithm big-o

问题陈述:您将获得一个数字N,并且您必须判断是否存在数字K,以便从1到K的所有数字中的BITS总和等于N.如果存在则打印该数字,否则打印“不存在。”没有引号。

问题链接:http://www.spoj.com/problems/BIT2/

我的代码复杂度为O((log n)^2)并且获得了TLE人们建议我可以在O(log n)中完成,但我无法弄明白。  有人可以帮助我在log n中完成此操作。

下面是我的代码,其中有一些预先计算+ log(n)^2这就是我所做的。

Solution

2 个答案:

答案 0 :(得分:1)

提示

你几乎就在那里,考虑你的TotalBits功能:

LL Total_Bits(LL n)
{  
    if(n==0) return 0;
    LL m = Lmb(n);
    n = n - pow(2,m);
    return (n+1) + Total_Bits(n) + m*pow(2,(m-1));
}

您需要做的是将此函数转换为在给定目标位数的情况下在单个调用中计算n的位(从最高有效到最低有效)的函数。这允许您从使用二分法中删除logn因子。

你怎么能弄清楚n的位?好吧,假如我们在m位置需要1,那么我们正在努力解决问题。您可以从代码中看到,如果n> = 2 ** m,那么答案将至少为m * pow(2,(m-1)+1,如果n <2 ** m,则答案将为少了。

Python代码

def find_index(N):
    """Compute the index K such that sum of all bits in numbers 1..K is N"""
    prefix = 0 # Number of 1's in the answer
    answer = 0 # Lower bound on index K
    for m in xrange(63,-1,-1):
        a = 1 << m
        extra = a*prefix + (m*(1<<m)>>1) # Amount we would add to our count if bit m is set
        if N>extra:
            N -= extra
            prefix += 1
            answer += a
    N-=prefix
    return answer if N==0 else "Does Not Exist."

答案 1 :(得分:0)

这是我在O((log n)^ 2)中的解决方案。你做的预计算不是必要的,而且价格昂贵。要检查给定数字K的方式,从1到K获取数字1的数量,请检查Count total set bits in all numbers from 1 to n。知道了,剩下的就是简单的二元搜索。我的解决方案

#include <bits/stdc++.h>

using namespace std;

typedef unsigned long long ui64;

ui64 ones(ui64 n){
    ui64 ans = 0;
    int x = 0;
    for(int i = __lg(n); i >= 0; --i)
        if(n & 1LLU << i)
            ans += ((1LLU << i) >> 1) * i + 1 + (1LLU << i) * x++;
    return ans;
}

int main(){
    int t;
    ui64 n, l, u, m;
    scanf("%d",&t);
    while(t--){
        scanf("%llu",&n);
        l = 0; u = n + 1;
        while(l != u){
            m = l + (u - l) / 2;
            if(ones(m) >= n) u = m;
            else l = m + 1;
        }
        if(ones(l) == n) printf("%llu\n",l);
        else printf("Does Not Exist.\n");
    }
}