p次方求和
时间限制:
1000 ms | 内存限制:
65535 KB
难度:3
-
描述
-
一个很简单的问题,求1^p+2^p+3^p+……+n^p的和。
-
输入
-
第一行单独一个数字t表示测试数据组数。接下来会有t行数字,每行包括两个数字n,p,
输入保证0<n<=1000,0<=p<=1000。
输出
- 输出1^p+2^p+3^p+……+n^p对10003取余的结果,每个结果单独占一行。 样例输入
-
210 110 2
样例输出
-
55385
-
第一行单独一个数字t表示测试数据组数。接下来会有t行数字,每行包括两个数字n,p,
快速幂取模
假如求 x ^ n 次方
我们可以把 n 表示为 2^k1 + 2k2 + 2^k3....,可以证明所有数都可以用前式来表示。(其实就是二进制表示数的原理)
那么 x^n = x^2^k1 * x^2^k2 * x^2^k3......
那么就可以利用二进制来加快计算速度了。
假如 x^22 , 22转化为二进制为 10110, 即 x^22 = x^16 * x^4 * x^2;
参考博客:http://blog.csdn.net/y990041769/article/details/22311889
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long LL;
LL qpow(int x, int b, int mod) {
LL res = 1;
x %= mod;
while(b > 0) {
if(b & 1) res = (res * x) % mod;
x = (x * x) % mod;
b >>= 1;
}
return res;
}
int main(){
//freopen("input.txt","r", stdin);
//freopen("output.txt", "w", stdout);
int t;
scanf("%d", &t);
while(t--) {
int n, p;
scanf("%d %d", &n, &p);
int i;
LL ans = 0;
for(i = 1; i <= n; i++) {
ans = (ans + qpow(i, p, 10003)) % 10003;
}
printf("%lld\n", ans);
}
return 0;
}