Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.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++ 计算一个数的2模幂的最快方法是什么_C++_C_Algorithm_Optimization_Numbers - Fatal编程技术网

C++ 计算一个数的2模幂的最快方法是什么

C++ 计算一个数的2模幂的最快方法是什么,c++,c,algorithm,optimization,numbers,C++,C,Algorithm,Optimization,Numbers,对于1可以在O(logn)中求解 例如,对于n=1234=10011010010(在基数2中),我们有n=2+16+64+128+1024,因此2^n=2^2*2^16*2^64*2^128*2^1024 请注意,2^1024=(2^512)^2,因此,如果您知道2^512,您可以在几次操作中计算2^1024 解决方案如下(伪代码): constulong模=100000007; 乌龙木尔(乌龙a、乌龙b){ 返回(a*b)%模; } 乌龙加(乌龙a、乌龙b){ 返回(a+b)%模; } int

对于
1可以在
O(logn)
中求解

例如,对于n=1234=10011010010(在基数2中),我们有n=2+16+64+128+1024,因此2^n=2^2*2^16*2^64*2^128*2^1024

请注意,2^1024=(2^512)^2,因此,如果您知道2^512,您可以在几次操作中计算2^1024

解决方案如下(伪代码):

constulong模=100000007;
乌龙木尔(乌龙a、乌龙b){
返回(a*b)%模;
}
乌龙加(乌龙a、乌龙b){
返回(a+b)%模;
}
int[]分解(ulong数){
//对于1234,它应该返回[1,4,6,7,10]
}
//对于x,它返回2^(2^x)模
//(例如,对于x=10,它返回2^1024模的模)
ulong power\u of\u power\u of\u 2\u mod(整数功率){
ulong结果=1;
for(int i=0;i
注意,
O(logn)
实际上是
O(1)
用于
ulong
参数(作为logn<63);并且该代码与任何模(模<2^32)兼容,与模是否为素数无关。

这将更快(C中的代码):

它可以在O((logn)^2)中求解。 尝试以下方法:-

unsigned long long int fastspcexp(unsigned long long int n)
{
    if(n==0)
        return 1;
    if(n%2==0)
        return (((fastspcexp(n/2))*(fastspcexp(n/2)))%1000000007);
    else
        return ( ( ((fastspcexp(n/2)) * (fastspcexp(n/2)) * 2) %1000000007 ) ); 
}

这是一种递归方法,速度非常快,足以满足大多数编程竞赛的时间要求。

此方法不使用O(log(n))复杂度的递归。看看这个

#define ull unsigned long long
#define MODULO 1000000007

ull PowMod(ull n)
{
    ull ret = 1;
    ull a = 2;
    while (n > 0) {
        if (n & 1) ret = ret * a % MODULO;
        a = a * a % MODULO;
        n >>= 1;
    }
    return ret;
}
这是pseudo from(参见从右到左的二进制方法部分)


如果您还想存储该数组,即(2^i)%mod[i=0到任意值],则:

long mod = 1000000007;
long int pow_mod[ele]; //here 'ele' = maximum power upto which you want to store 2^i
pow_mod[0]=1; //2^0 = 1
for(int i=1;i<ele;++i){
    pow_mod[i] = (pow_mod[i-1]*2)%mod;
}
long mod=100000007;
长整数功率模式[ele]//这里的‘ele’=要存储2^i的最大功率
功率模[0]=1//2^0 = 1

对于(inti=1;我认为非常好。如果
,也许我会删除第一个
,也就是说,总是转到一般情况。这是数学问题……100000007是素数,你应该看看这里:@astreal的Check和binary方法:非常感谢。我应该知道
素数
,羞耻!可能是Nice的重复。但这是可能的(虽然不一定)以摆脱递归。可以计算2的不同幂次的resid,即2^1、2^2、2^4、2^8等。此计算是按直接顺序迭代完成的。然后对实际幂次进行排序,以显示所需的“成分”这不应该是
e==1
分支中的
res=x%mod
吗?@Christoph如果
x>=mod
,那是绝对的。问题:
res*res
很容易溢出。建议
uint32-PowMod(uint32-x,uint32-e,uint324-mod)
,并用64位数学做
*
。2:Minor
PowMod(0,e>0,…)
应返回0。
PowMod(…,0,1)
应返回0.O(log(n)^2)方法。您确定不应手动删除公共子表达式吗?@chux a*a<100000007^2<2^60,而长-长限制为2^63,因此无需担心-对于OP的范围为“1”
unsigned long long int fastspcexp(unsigned long long int n)
{
    if(n==0)
        return 1;
    if(n%2==0)
        return (((fastspcexp(n/2))*(fastspcexp(n/2)))%1000000007);
    else
        return ( ( ((fastspcexp(n/2)) * (fastspcexp(n/2)) * 2) %1000000007 ) ); 
}
#define ull unsigned long long
#define MODULO 1000000007

ull PowMod(ull n)
{
    ull ret = 1;
    ull a = 2;
    while (n > 0) {
        if (n & 1) ret = ret * a % MODULO;
        a = a * a % MODULO;
        n >>= 1;
    }
    return ret;
}
function modular_pow(base, exponent, modulus)
Assert :: (modulus - 1) * (base mod modulus) does not overflow base
result := 1
base := base mod modulus
while exponent > 0
    if (exponent mod 2 == 1):
       result := (result * base) mod modulus
    exponent := exponent >> 1
    base := (base * base) mod modulus
return result
long mod = 1000000007;
long int pow_mod[ele]; //here 'ele' = maximum power upto which you want to store 2^i
pow_mod[0]=1; //2^0 = 1
for(int i=1;i<ele;++i){
    pow_mod[i] = (pow_mod[i-1]*2)%mod;
}