Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 位的总和是给定的,用于查找塔尔数_C++_Algorithm_Big O - Fatal编程技术网

C++ 位的总和是给定的,用于查找塔尔数

C++ 位的总和是给定的,用于查找塔尔数,c++,algorithm,big-o,C++,Algorithm,Big O,问题陈述:将给您一个数字N,您必须判断是否存在一个数字K,以便从1到K的所有数字中的位总和等于N。如果存在,则打印该数字,否则打印“不存在”。不带引号 问题链接: 我的代码复杂度是O((logn)^2),人们建议我可以在O(logn)中完成,但我无法理解。 有人能帮我在logn中怎么做吗 下面是我的代码和一些预计算+log(n)^2这就是我所做的 提示 你几乎已经在那里了,考虑一下你的总计函数: LL Total_Bits(LL n) { if(n==0) return 0;

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

问题链接:

我的代码复杂度是
O((logn)^2)
,人们建议我可以在
O(logn)
中完成,但我无法理解。 有人能帮我在
logn
中怎么做吗

下面是我的代码和一些预计算+
log(n)^2
这就是我所做的

提示

你几乎已经在那里了,考虑一下你的总计函数:

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这里是我在O((logn)^2)中的解。您所做的预计算是不必要的,而且是昂贵的。要检查如何给定一个数字K,从1到K的数字中获取1的数量,请检查此项。知道了这一点,剩下的是一个简单的二进制搜索。我的解决方案:

#包括
使用名称空间std;
typedef无符号长ui64;
ui64系列(ui64 n){
ui64 ans=0;
int x=0;
对于(int i=\u lg(n);i>=0;--i)
如果(n&1LLU 1)*i+1+(1LLU=n)u=m;
否则l=m+1;
}
如果(一(l)==n)printf(“%llu\n”,l);
else printf(“不存在。\n”);
}
}

当你说O(log n ^ 2)时,你是指O((log n)^ 2)还是O(log(n ^ 2))?因为O(log(n ^ 2))=O(2 log n)=O(log n)。@ Sh希奇抱歉它的O((log n)^ 2)@ C++。^2
?(我之所以这样问,是因为我认为它是
O(log(n)^3)
)取决于您可能找到的编译器(我使用的是二进制搜索,因为二进制搜索在O(log n)中运行,它将调用函数Total_Bits O(log n)乘以总位的复杂度是log n,二进制搜索在log n中,而总复杂度是O((log n)^2),如果我错了,请纠正我。谢谢你@Peter de Rivaz的这个好主意。
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."
#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");
    }
}