我一直在编写以下重现关系的程序:
An = 5An-1 - 2An-2 - An-3 + An-4
输出应为答案模数10 ^ 9 + 7 .. 我为此写了一个蛮力的方法如下......
long long int t1=5, t2=9, t3=11, t4=13, sum;
while(i--)
{
sum=((5*t4) - 2*t3 - t2 +t1)%MOD;
t1=t2;
t2=t3;
t3=t4;
t4=sum;
}
printf("%lld\n", sum);
其中MOD= 10^9 +7
每一件事似乎都是真的..但我对某些价值观得到了否定的答案..由于这个问题,我无法找到正确的解决方案......
Plz帮助保留Modulus
答案 0 :(得分:31)
问题是%运算符不是“模运算符”,而是具有以下相等性的“除数余数”运算符
(a/b)*b + a%b == a (for b!=0)
所以,如果你的整数除法向零舍入(我认为这是自C99和C ++ 11以来的强制执行),-5 / 4将为-1而且我们有
(-5/4)*4 + -5%4 == -5
-1 *4 -1 == -5
为了获得正结果(对于模运算),你需要添加除数,以防余数为负数或做类似的事情:
long mod(long a, long b)
{ return (a%b+b)%b; }
答案 1 :(得分:6)
在@ sellibitze和@ liquidblueocean的答案中第二次使用%
可能不会像%
一般慢,因为它归结为b
或减去任何一个减法。实际上,让我检查一下......
int main(int argc, char **argv) {
int a = argc; //Various tricks to prevent the
int b = 7; //compiler from optimising things out.
int c[10]; //Using g++ 4.8.1
for (int i = 0; i < 1000111000; ++i)
c[a % b] = 3;
//c[a < b ? a : a-b] = 3;
return a;
}
或者用%
或其他行评论该行,我们得到:
%
:14秒
?
:7秒
所以%
并不像我怀疑的那样优化。可能是因为优化会增加开销。
因此,出于性能原因,最好不要使用%
两次。
相反,正如this answer建议并解释的那样,执行此操作:
int mod(int k, int n) {
return ((k %= n) < 0) ? k+n : k;
}
需要a bit more work if you want it to work properly for negative n
too,但这几乎不需要。
答案 2 :(得分:5)
只需用处理负值的函数替换%
:
long long int mod(long long int a, long long int b) {
long long int ret = a % b;
if (ret < 0)
ret += b;
return ret;
}
编辑:将数据类型更改为long long int
。
答案 3 :(得分:3)
当abs(a)&gt;时,目前所有在公式中一次性添加的答案都是错误的。湾使用这个或类似的:
int modulo (int a, int b) { return a >= 0 ? a % b : ( b - abs ( a%b ) ) % b; }
答案 4 :(得分:1)
正如其他人所说%
只是一个余数运算符而不是mod
。但是,mod / remainder操作通过像这样的递归关系正确分配,所以如果你只是调整你的最终解决方案是正面的,就像这样,
if (sum < 0) { sum = sum + MOD; }
那么你应该得到正确的答案。这样做的好处是,每循环迭代引入一个较少的函数调用和/或分支。 (根据编译器的聪明程度,这可能有问题,也可能没关系。)