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:MinorPowMod(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;
}