bigpotato

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Your task is to calculate ab mod 1337 where a is a positive integer and b is an extremely large positive integer given in the form of an array.

Example1:

a = 2
b = [3]

Result: 8

Example2:

a = 2
b = [1,0]

Result: 1024

 

计算ab%1337,其中a、b均为正整数,且b非常大,用一个数组表示每一位数字。

分析:

  直接a自乘b次,再对1337求余,虽然理论上可行,但是存在两个很大的问题:

  1. 溢出;
  2. 执行效率太低。

所以必须进行优化。

  对于1,我们知道ab%n=(a%n)b%n,因此,可先将a对1337求余,以将a调整到1337以内,若a是个很大的数,这样做可显著的降低计算的数量级。

  对于2,因为b是一个非常大的数,我们不能一次一次乘。可通过二分法来优化。

  此外,由于b以数组的形式表示,我们知道,ak=(ak0*10)*(ak1),其中k为一个两位数,k0为k的10位数,k1为k的个位数。因此,我们可从b的最高位开始计算(第0个元素),将ab[0]结果存储在rst中,接着取出b[1],计算ab[1],将rst更新为(rst10)*(ab[1]),然后取出b[2],rst更新为(rst10)*(ab[2]),…,如此循环,直至b中最后一个元素。注意在每次更新rst时,可先对1337求余,以降低数量级。

代码如下:

int pow(int x, int n)
{
	if (n == 0)
		return 1;
	if (n == 1)
		return x % 1337;
	if (x == 1)
		return 1;
	int rst = 1, tmp = x;
	while (n > 0)
	{
		if (n % 2)
			rst = rst*tmp % 1337;
		tmp = tmp*tmp % 1337;
		n /= 2;
	}
	return rst % 1337;
}

int superPow(int a, vector<int>& b)
{
	int rst = 1;
	a %= 1337;
	for (int i = 0; i < (int)b.size(); i++)
		rst = pow(rst, 10)*pow(a, b[i]) % 1337;
	return rst;
}

  

posted on 2018-03-23 11:05  bigpotato  阅读(164)  评论(0)    收藏  举报