一、题目
问题描述
将一个数N分为多个正整数之和,即N=a1+a2+a3+…+ak,定义M=a1a2a3*…*ak为N的潜能。
给定N,求它的潜能M。
由于M可能过大,只需求M对5218取模的余数。
输入格式
输入共一行,为一个正整数N。
输出格式
输出共一行,为N的潜能M对5218取模的余数。
样例输入
10
样例输出
36
数据规模和约定
1<=N<10^18
二、思路
具体思路可见文末参考博客。
先来看几个数找找规律:4=2+2,5=2+3,6=3+3,7=3+2+2,8=3+3+2,9=3+3+3
发现规律如下:
(1)元素不会超过4,因为4=2+2,又可以转化为2的问题,而5=2+3,5<2*3,所以5总能分解成2和3。
(2)尽可能多分解出3,然后分解出2,不要分出1。
考虑任意一个数,除以3之后的结果有以下3种:
(1)能被3除断(即整除),那么就分解为3+3+…+3的情况即可。例如:9=3+3+3。
(2)被3除余1,分解为3+3+…+3+2+2或者3+3+…+3+4的情况,例如:10=3+3+2+2
(3)被3除余2,分解为3+3+…+3+2的情况,例如:11=3+3+3+2。
所以最好是分解成连续的3,或附带一两个2。
那么关键问题就变成了 3的k次方取模 的问题,这个用快速幂可以解决。
具体快速幂可见文末参考视频链接。
三、代码
//正整数N分解使得乘积M最大问题
#include <iostream>
using namespace std;
typedef long long ll;
#define p 5218 //余数
int fastPow(int a,ll k) //递归实现快速幂
{
//递归出口
if (k == 0)
return 1;
if (k == 1)
return a;
ll t = fastPow(a, k / 2) % p;
if (k % 2 == 0) //如果k是偶数
return t * t % p;
return t * t * a % p;
}
int main()
{
ll N;
cin >> N;
if (N <= 2)
{
cout << N;
return 0;
}
if (N % 3 == 0) //如果能够被3直接整除
{
ll k = N / 3; //问题就转化为3的k次方模p
cout << fastPow(3,k);
return 0;
}
if (N % 3 == 1)
{
ll k = N / 3 - 1;
cout << fastPow(3,k) * 4 % p;
return 0;
}
if (N % 3 == 2)
{
ll k = N / 3;
cout << fastPow(3, k) * 2 % p;
return 0;
}
}
四、遇到的问题
在实现快速幂函数时,误将k定义为int类型,导致错误
五、参考
B站
快速幂问题