nyoj 420 p次方求和 (快速幂)

来源:互联网 发布:私有云平台网络拓扑图 编辑:程序博客网 时间:2024/05/21 17:49

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

快速幂取模

假如求 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;}


0 0