我正在查看Codechef中的实践问题,我发现了这个问题。我是Python新手。我已经使用Python3编写了以下代码。我不断收到“ 超出时间限制”错误。寻找代码的一些优化。
问题陈述如下:
给出n和m,计算1 ^ 1 + 2 ^ 2 + 3 ^ 3 + ... + n ^ n模m。
输入: 第一行包含1≤t≤10(测试用例的数量)。然后是测试用例定义。每个测试用例的形式为:1≤n 1018,1≤m≤200000
示例
Input:
6
1 100000
2 100000
3 100000
4 100000
5 100000
6 100000
Output:
1
5
32
288
3413
50069
这是我的代码:
t = int(input())
for j in range (1,t+1):
ans = 0
n, m = [int(x) for x in input().split()]
for i in range (1,n+1):
ans = (ans + pow(i,i))%m
print (ans)
谢谢。
答案 0 :(得分:0)
O(m log n)中的解决方案:
def geometric(n,b,m):
T=1
e=b%m
total = 0
while n>0:
if n&1==1:
total = (e*total + T)%m
T = ((e+1)*T)%m
e = (e*e)%m
n = n//2
return total
def efficient_solve(n, m):
ans = 0
for x in range(1, min(n, m) + 1):
k = pow(x, m, m)
s = pow(x, x, m)
times = (n // m) + (x <= n % m)
ans += s * geometric(times, k, m)
ans = ans % m
return ans
geometric计算取自https://stackoverflow.com/a/42033401/3308055
的模的几何级数m说明
N太大,我们需要一种在一次操作中计算多个和结果的方法。
请注意, 如果我们开始进行分配,则几乎所有结果将至少具有1 mk作为因子,而 唯一没有mk因子的结果将是 因此,如果n = 5且m = 3,我们可以求解 这很好,但是我们仍然需要执行O(n)运算。让我们尝试将其中一些总和进行分组。我们将基于 我们如何有效地计算每个小组的结果?
注意,对于每个组,我们都有相同的底数,并且每个和的指数增加m。如果我们知道第一个和( 我们每个小组有多少笔款项?好吧,每n 我们将 我们致电 求解该组所有和的结果将是: 这等效于: 这里有一个几何级数,可以高效地进行计算。这样,我们就有了计算问题答案所需的一切。x ^ x % m = (mk + i) ^ (mk + i) % m
的i (mk + i) ^ (mk + i) % m = (mk + i) * (mk + i) * (mk + i) * ... * (mk + i)
(mk + i)次mk * whatever % m
将为0。i * i * i * i * ... * i
(mk + i)倍。即i^(mk + i)
。1^1 + 2^2 + 3^3 + 4^4 + 5^5 % 3
而不是求解1 ^ (0 + 1) + 2 ^ (0 + 2) + 0 ^ (3 + 0) + 1 ^ (3 + 1) + 2 ^ (3 + 2) % m
。i % m
进行分组,共有3个分组:
1 ^ (0 + 1) + 1 ^ (3 + 1)
2 ^ (0 + 2) + 2 ^ (3 + 2)
0 ^ (3 + 0)
1 ^ (0 + 1)
)的结果,那么下一个和(1 ^ (3 + 1)
)相对于%m会如何变化?1 ^ (3 + 1) % m = (1 ^ 1 % m) * (1 ^ 3 % m) % m
。如果n更高,并且我们在这个组中有1 ^ (6 + 1)
,则为1 ^ (6 + 1) % m = (1 ^ 1 % m) * (1 ^ 3 % m) * (1 ^ 3 % m) % m
。请注意,对于同一组中的每个随后的总和,我们只需要添加(1 ^ 3 % m)
的结果。一般来说,我们需要添加base ^ m % m
。x
称为组的索引,该索引也将成为指数的基础。我们将有min(n,m)个组k
的结果x ^ m % m
。让我们将s
的结果称为x ^ x % m
。s + s * k + s * k^2 + s * k^3 ... + s * k^(times - 1)
s * (1 + k + k^2 + k^3 ... + k^(times - 1))
答案 1 :(得分:0)
numpy解决方案
import numpy as np
n = 6
m = 100000
arange = np.arange(1, n+1)
power = np.power(arange, arange)
result = np.cumsum(power) % m