STFM - Editorial

Can you please elaborate your doubt? What part you did not understand?

You should ask your question as an actual question in the Forum. You most probably won’t get an answer if you post your question as an answer to another question

to calculate ( a / b ) % m you need to find multiplicative inverse of 2 modulo m and to calculate that m and b must me coprime.

As said above (AB)%M=((A%M)(B%M)%M)…so lets consider a case where we need to calculate the factorial of 5.What we will do is calculate the factorial and perform the modulo operation on it.

fact=1; for i=1 to i<=5: fact=((fact%M)*(i%M))M; do it this way and you will get the correct answer.
Note : M here being the number whose modulo the answer should be.

Maybe you just shouldn’t use Python for 10^7 operations. Slow languages are slow.

2 Likes

Then maybe they shouldn’t allow it, or (preferably) they should accommodate for it…I am learning, and only 1 language at a time…

Also, I think that even with the alternative formula, the timing problem is the same, as (x+1)! is still same number of multiplications…

So problem is impossible for python? Is that the answer?

You dont need to calculate 107…instead you need to calculate (107)%M for the given M and its not a big deal to calculate (10**7)%M…

Just a guess,

     if(x%2==0)
        return (x%m*(x/2)%m*(x+1)%m)%m;
    else
        return (x%m*x%m*((x+1)/2)%m)%m;

It looks like these expression gets overflowed. I am not sure about though. I can give you the testfile on which you are getting wrong answer though.

1 Like

Thanks for the prompt reply but, that doesnt seem to be the problem… I’ve changed the return type to ULL and added yet another mod just to be sure and I only get WA on those 3 flies… :confused: weird

I have the same problem… did you find the error?

Modulo and multiplication have the same precedence, so that expression is evaluated left-to-right:

  • x=a
  • a%m=b
  • b*(x/2)=c
  • c%m=d

etc. Since b can be around 10^9 and x/2 around 10^18, it’s not hard to see that overflow occurs when computing c.

1 Like

Hey @xellos0, nice, thanks for the tip, so… how can I fix that above code? :confused:

"This means, we can reduce the task to multiply 3 numbers up to 10^7 (the modulo value) by doing modulo M for each of the numbers before multiplication. "

isnt this what I’m doing?

M <= 10^7… and if x < M then, yes, you do, as stated in the editorial. Let’s store the sum of 1āˆ—1!+2āˆ—2!+…xāˆ—x! for each x≤M

No. We precalculate all the values upto M beforehand. So we can answer for each integer in O(1). That’s why O(M+N)

1 Like

Is this correct?

unsigned long long int divparcel(unsigned long long int x, int m)
{
if(x%2==0)
return (((x%m*(x/2)%m)%m)(x+1)%m)%m;
else
return ((x%m
x%m)%m*((x+1)/2)%m)%m;
}

Just use parentheses, Luke. (And use them correctly. You added them everywhere except where you needed them.)

x/2 is not up to 1e7. x/2 is up to 5e18. (x/2)%M is up to 1e7. It’s b*(x/2)=c, not b*((x/2)%M)=c (note the parentheses).

((((x%m)((x/2)%m))%m)((x+1)%m))%m is the right way. Or just store x,x/2,x+1 in separate variables first, mod these variables and then multiply them while modding again, if you want a cleaner code.

@kuruma,@xellos0 :We can also use modular multiplication for finding (a*b)%m in O(log(n))(it can be optimised further to calculate in constant time).

You can check my solution for further details :-

http://www.codechef.com/viewsolution/6119518

@knb_dtu Occam’s razor: don’t use more than necessary. Anything more than ((a%m)*(b%m))%m is unnecessary. (How much time would you waste during a contest by overcomplicating things like this?)

@xellos0, Finally got AC… Such a stupid thing!! Thanks a ton!!

1 Like