有人可以让我知道一个有效的大n算法(比如10 ^ 10)来找到上述系列的总和吗?
我的代码在n = 100000和m = 200000
时被克隆#include<stdio.h>
int main() {
int n,m,i,j,sum,t;
scanf("%d%d",&n,&m);
sum=0;
for(i=1;i<=n;i++) {
t=1;
for(j=1;j<=i;j++)
t=((long long)t*i)%m;
sum=(sum+t)%m;
}
printf("%d\n",sum);
}
答案 0 :(得分:23)
两个注释:
(a + b + c) % m
相当于
(a % m + b % m + c % m) % m
和
(a * b * c) % m
相当于
((a % m) * (b % m) * (c % m)) % m
因此,您可以使用O(log p )中的递归函数计算每个项:
int expmod(int n, int p, int m) {
if (p == 0) return 1;
int nm = n % m;
long long r = expmod(nm, p / 2, m);
r = (r * r) % m;
if (p % 2 == 0) return r;
return (r * nm) % m;
}
使用for
循环求和元素:
long long r = 0;
for (int i = 1; i <= n; ++i)
r = (r + expmod(i, i, m)) % m;
此算法为O( n log n )。
答案 1 :(得分:5)
我认为你可以使用欧拉定理来避免一些指数,因为phi(200000)= 80000。中国剩余定理也可能有所帮助,因为它减少了模数。
答案 2 :(得分:3)
您可以查看我对this post的回答。那里的实施略有错误,但这个想法就在那里。关键策略是找到x使得n ^(x-1)
答案 3 :(得分:1)
我最近遇到了类似的问题:我的'n'是1435,'m'是10 ^ 10。这是我的解决方案(C#):
ulong n = 1435, s = 0, mod = 0;
mod = ulong.Parse(Math.Pow(10, 10).ToString());
for (ulong i = 1; i <= n;
{
ulong summand = i;
for (ulong j = 2; j <= i; j++)
{
summand *= i;
summand = summand % mod;
}
s += summand;
s = s % mod;
}
在结尾''等于所需的数字。
答案 4 :(得分:0)
你在这里被杀了吗?
for(j=1;j<=i;j++)
t=((long long)t*i)%m;
指数mod m可以使用平方和方法实现。
n = 10000;
m = 20000;
sqr = n;
bit = n;
sum = 0;
while(bit > 0)
{
if(bit % 2 == 1)
{
sum += sqr;
}
sqr = (sqr * sqr) % m;
bit >>= 2;
}
答案 5 :(得分:0)
我无法添加评论,但对于中国余数定理,请参阅http://mathworld.wolfram.com/ChineseRemainderTheorem.html公式(4) - (6)。