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

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;
}


你可能感兴趣的:(nyoj 420 p次方求和 (快速幂))