我发现pow(2,i)
可以在i
范围内0<=i<=100000.
i
除powers[100000];
powers[0]=1;
for (i = 1; i <=100000; ++i)
{
powers[i]=(powers[i-1]*2)%MOD;
}
之外,MOD = 1000000007
i=100000
对于i=70
,功率值不会大于MOD吗?
如何正确存放电量?
这个操作对我来说看起来不太可行。 我估计值正确到{{1}}最大值。
我必须找到sum + = ar [i] * power(2,i),最后打印总和%1000000007,其中ar [i]是一个附加数组,其中一些大数字高达10 ^ 5
答案 0 :(得分:2)
只要您的模数值小于数据类型容量的一半,就不会超过它。这是因为你取了0..1000000006
范围内的先前值,加倍它,然后重新模数它将它带回到相同的范围。
但是,我不能保证更高的价值不会给你带来麻烦,它比我准备投资的数学分析更为简单。您可以花费大量时间进行分析,检查和调试,但最好不要让问题首先发生。
另类?我倾向于使用预生成方法(让程序预先进行gruntwork,将预先生成的值轻松地插入到数组中,并且可以从真正的程序中快速访问)。 / p>
使用此方法,您可以使用经过良好测试和已知的工具来处理大量值。由于这些数据不会改变,因此每次程序启动时都无法计算数据。
如果您希望以简单(高效)的方式执行此操作,则以下bash
脚本与bc
和awk
一起执行此操作:
#!/usr/bin/bash
bc >nums.txt <<EOF
i = 1;
for (x = 0;x <= 10000; x++) {
i % 1000000007;
i = i * 2;
}
EOF
awk 'BEGIN { printf "static int array[] = {" }
{ if (NR % 5 == 1) printf "\n ";
printf "%s, ",$0;
next
}
END { print "\n};" }' nums.txt
bc
部分是&#34;肉&#34;这件事,它创造了两个大的力量,并以你提供的数量为模输出它们。 awk
部分只是用C风格的数组元素格式化它们,每行五个。
只需获取它的输出并将其放入您的代码中,瞧,你有它,一个编译时耗费的数组,你可以用来快速查找。
我的盒子只需要一秒半的时间来生成阵列,然后永远不会再次需要这样做。你也不必担心模数学的变幻莫测: - )
static int array[] = {
1,2,4,8,16,
32,64,128,256,512,
1024,2048,4096,8192,16384,
32768,65536,131072,262144,524288,
1048576,2097152,4194304,8388608,16777216,
33554432,67108864,134217728,268435456,536870912,
73741817,147483634,294967268,589934536,179869065,
359738130,719476260,438952513,877905026,755810045,
511620083,23240159,46480318,92960636,185921272,
371842544,743685088,487370169,974740338,949480669,
898961331,797922655,595845303,191690599,383381198,
766762396,533524785,67049563,134099126,268198252,
536396504,72793001,145586002,291172004,582344008,
164688009,329376018,658752036,317504065,635008130,
270016253,540032506,80065005,160130010,320260020,
640520040,281040073,562080146,124160285,248320570,
:
861508356,723016705,446033403,892066806,784133605,
568267203,136534399,273068798,546137596,92275185,
184550370,369100740,738201480,476402953,952805906,
905611805,
};
答案 1 :(得分:0)
如果您注意到您的模数可以存储在int中。 MOD = 1000000007(十进制)相当于0b00111011100110101100101000000111,可以32位存储。
- i pow(2,i) bit representation
- 0 1 0b00000000000000000000000000000001
- 1 2 0b00000000000000000000000000000010
- 2 4 0b00000000000000000000000000000100
- 3 8 0b00000000000000000000000000001000
- ...
- 29 536870912 0b00100000000000000000000000000000
当pow(2,i)比你的MOD = 1000000007更大时,棘手的部分开始,但如果你知道当前的pow(2,i)将大于你的MOD,你可以实际看到MOD之后的位是怎样的
- i pow(2,i) pow(2,i)%MOD bit representation
- 30 1073741824 73741817 0b000100011001010011000000000000
- 31 2147483648 147483634 0b001000110010100110000000000000
- 32 4294967296 294967268 0b010001100101001100000000000000
- 33 8589934592 589934536 0b100011001010011000000000000000
所以如果你有pow(2,i-1)%MOD,你可以在pow(2,i-1)%MOD上做* 2直到你下一次战斗(2,i)将大于MOD
在i = 34的示例中,您将使用(589934536 * 2)MOD 1000000007而不是(8589934592 * 2)MOD 1000000007,因为8589934592无法存储在int中。
另外,您可以尝试位操作而不是乘以pow(2,i)。 与乘法2相同的位操作是位shift left。