Is there any algorithm to calculate (1^x + 2^x + 3^x + ... + n^x) mod 1000000007
?
Note: a^b
is the b-th power of a.
The constraints are 1 <= n <= 10^16, 1 <= x <= 1000
. So the value of N is very large.
I can only solve for O(m log m)
if m = 1000000007
. It is very slow because the time limit is 2 secs.
Do you have any efficient algorithm?
There was a comment that it might be duplicate of this question, but it is definitely different.
I think Vatine’s answer is probably the way to go, but I already typed this up and it may be useful, for this or for someone else’s similar problem.
I don’t have time this morning for a detailed answer, but consider this.
1^2 + 2^2 + 3^2 + ... + n^2
would take O(n) steps to compute directly. However, it’s equivalent to(n(n+1)(2n+1)/6)
, which can be computed in O(1) time. A similar equivalence exists for any higher integral power x.There may be a general solution to such problems; I don’t know of one, and Wolfram Alpha doesn’t seem to know of one either. However, in general the equivalent expression is of degree x+1, and can be worked out by computing some sample values and solving a set of linear equations for the coefficients.
However, this would be difficult for large x, such as 1000 as in your problem, and probably could not be done within 2 seconds.
Perhaps someone who knows more math than I do can turn this into a workable solution?
Edit: Whoops, I see Fabian Pijcke had already posted a useful link about Faulhaber's formula before I posted.
You can sum up the series
with the help of Faulhaber's formula and you'll get a polynomial with an
X + 1
power to compute for arbitraryN
.If you don't want to compute Bernoulli Numbers, you can find the the polynomial by solving
X + 2
linear equations (forN = 1, N = 2, N = 3, ..., N = X + 2
) which is a slower method but easier to implement.Let's have an example for
X = 2
. In this case we have anX + 1 = 3
order polynomial:The linear equations are
Having solved the equations we'll get
The final formula is
Now, all you have to do is to put an arbitrary large
N
into the formula. So far the algorithm hasO(X**2)
complexity (since it doesn't depend onN
).There are a few ways of speeding up modular exponentiation. From here on, I will use
**
to denote "exponentiate" and%
to denote "modulus".First a few observations. It is always the case that
(a * b) % m
is((a % m) * (b % m)) % m
. It is also always the case thata ** n
is the same as(a ** floor(n / 2)) * (a ** (n - floor(n/2))
. This means that for an exponent <= 1000, we can always complete the exponentiation in at most 20 multiplications (and 21 mods).We can also skip quite a few calculations, since
(a ** b) % m
is the same as((a % m) ** b) % m
and if m is significantly lower than n, we simply have multiple repeating sums, with a "tail" of a partial repeat.