求12345^12345的所有约数(即因子)之和,并对其取模9901再输出。
key格式:CTF{xxx}
这里存在三个有趣的数学定理:
(1)整数唯一分解定理
(2)约数和公式
(3)同余模公式
上百度搞懂这三个公式就可以学习这道题目了。
#include<bits/stdc++.h>
using namespace std;
const int size = 10000;
const int mod = 9901;
long int sum(long int p, long int n);
long int power(long int p, long int n);
int main()
{
long int a, b;
long int p[size];
long int n[size];
while(cin >> a >> b)
{
long int i, k = 0;
for(i = 2; i * i <= a; )
{
if(a % i == 0)///一旦出现质因子
{
p[k] = i;///质因子是多少
n[k] = 0;///质因子次数初始化
while(!(a % i))///标记质因子能被整除的次数
{
n[k]++;
a /= i;
}
k++;
}
///素数刷一遍
if(i == 2)///这么做是因为除了2以外,素数均为奇数
i++;
else
i += 2;
}
if(a != 1)///特殊处理:这个数本身就是质数
{
p[k] = a;
n[k++] = 1;
}
long int ans = 1;
for(i = 0; i < k; i++)///普普通通地刷过一遍。。递归二分、反复平方是核心
{
ans = (ans * (sum(p[i], n[i] * b) % mod)) % mod;
cout << ans << endl;
}
}
return 0;
}
long int sum(long int p, long int n)///递归二分求等比序列
{
if(n == 0)
return 1;
if(n % 2)///指数为奇
return (sum(p, n / 2) * (1 + power(p, n / 2 + 1))) % mod;
else///指数为偶
return (sum(p, n / 2 - 1) * ( 1 + power(p, n / 2 + 1)) + power(p, n / 2)) % mod;
}
long int power(long int p, long int n)///反复平方
{
long int sq = 1;
while(n > 0)
{
if(n % 2)
sq = (sq * p) % mod;///这么做就是为了奇次幂腾出来一个p
n /= 2;
p = p * p % mod;
}
return sq;
}