This question already has an answer here:
I have been writing a program for the following recurrence relation:
An = 5An-1 - 2An-2 - An-3 + An-4
The output should be the Answer modulus 10^9 + 7.. I wrote a brute force approach for this one as follows...
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);
where MOD= 10^9 +7
Every thing seems to be true.. but i am getting negative answer for some values.. and due to this problem, I am unable to find the correct solution...
Plz help about the right place to keep the Modulus
Just replace
%
by a function that handles negative values:EDIT: Changed the data type to
long long int
.The thing is that the % operator isn't the "modulo operator" but the "division remainder" operator with the following equality
So, if in case your integer division rounds towards zero (which is mandated since C99 and C++11, I think), -5/4 will be -1 and we have
In order to get a positive result (for the modulo operation) you need to add the divisor in case the remainder was negative or do something like this:
All answers currently here that have a once-off addition in their formula are wrong when abs(a) > b. Use this or similar:
As others have said
%
is just a remainder operator rather thanmod
. However, the mod/remainder operation distributes correctly through recurrence relations like this, so if you just adjust your final solution to be positive, like this,then you should get the right answer. The advantage of doing it this way is that you introduce one less function call and/or branch per loop iteration. (Which may or may not matter depending on how clever your compiler is).
Using
%
a second time in @sellibitze's and @liquidblueocean's answers probably won't be as slow as%
tends to be in general, because it boils down to either one subtraction ofb
or none. Actually, let me just check that...Alternatively commenting the line with
%
or the other line, we get:With
%
: 14 secondsWith
?
: 7 secondsSo
%
is not as optimised as I suspected. Probably because that optimisation would add overhead.Therefore, it's better to not use
%
twice, for performance reasons.Instead, as this answer suggests and explains, do this:
It takes a bit more work if you want it to work properly for negative
n
too, but that's almost never necessary.