题目描述
假设现在有两个自然数A和B,S是AB的所有约数之和。
请你求出S mod 9901的值是多少。
输入格式
在一行中输入用空格隔开的两个整数A和B。
输出格式
输出一个整数,代表S mod 9901的值。
数据范围
$0≤A,B≤5×10^7$
输入样例:
2 3
输出样例:
15
注意: A和B不会同时为0。
感谢@hkr04大佬指出本题目代码效率有点低,导致TLE.
现在已经加入剪枝优化AC了,大家可以放心食用.
正解
(数学(质因数分解,唯一分解定律,约数和公式),分治递归)
数学类分析
- 质因数分解,就是将一个数分解成为 ${p_1}^{c1} \times {p_2}^{c_2} \times … \times {p_n}^{c_n}$ 比如说$24={2}^{3}\times{3}^{1}$
- 唯一分解定律,就是字面意思
- 约数和公式,如下文所示
${A}^{B}=(1 \+ {p_1}^{1} \+ {p_1}^{2} \+ ..... \+ {p_1}^{B \* c_1}) \times (1 \+ {p_2}^{2} \+ ..... \+ {p_n}^{B \times c_2}$)
$ sum(p,c)= {1} \+ {p} \+ {p^2} \+ … \+ {p^c} $
然后呢我们可以通过分类以及乘法中的提取公因式法,将sum函数中c为奇数的公式和sum函数中c为偶数的公式推出。具体参考《算法竞赛进阶指南》,亦可以看我的cpp代码中的sum函数。
C++ 代码
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
#define Mod 9901
int a,b;
int ksm(int a,int b)//快速幂函数
{
int ans=1;
a%=Mod;
while(b)
{
if (b&1)
ans=ans%Mod*a;
a=a%Mod*a%Mod;
b>>=1;
}
return ans;
}
long long sum(int p,int c)
{
if (c==0)
return 1;
if(c&1)
return ((1+ksm(p,(c+1)>>1))*sum(p,(c-1)>>1))%Mod;//奇数的情况下
else
return ((1+ksm(p,c>>1))*sum(p,(c>>1)-1)+ksm(p,c))%Mod;//偶数的情况下
}
int main()
{
cin>>a>>b;
int ans=1;
for (int i=2;i<=a;i++)
{
int s=0;
while(a%i==0)
{
s++;
a/=i;
}
if (s)//这句话剪枝.然后就TLE变成了AC.by POJ
ans=ans*sum(i,s*b)%Mod;
}
if (a==0)
cout<<0<<endl;//特判的情况,这里非常的阴毒,出题人用心险恶
else
cout<<ans<<endl;
return 0;
}
约数和公式似乎是
$$S=(1 + {p_1}^{1} + {p_1}^{2} + \dots + {p_1}^{B * c_1}) \times (1 + {p_2}^{2} + \dots + {p_2}^{B \times c_2}) \times \dots \times (1 + {p_n}^{1} + {p_n}^{2} + \dots + {p_n}^{B * c_n})$$
大佬们能帮忙解答吗 https://www.acwing.com/video/116/
大佬,还是你的代码适合我
hhhhh好搞笑最后一句注释
Orz
%%%%Orz
/WoW/
∏ni=1∑B×cik=0pkiS=∏i=1n∑k=0B×cipik
唯一分解,不是要求乘子是质因数吗,当i为4时 ,乘子不就不是质数了吗?
2是质数哦
一开始我也想到这个问题,但实际上i从小到大,当i为4时,已经被i = 2整除完了,就不可能再被4整除了
nb!!!
QwQ
为什么是$A^B=\prod_{i=1}^{n}\sum_{k=0}^{B\times c_i}p_i^{k}$
不应该是$S=\prod_{i=1}^{n}\sum_{k=0}^{B\times c_i}p_i^{k}$,S为约数和
吗?
这里有解释,太旧了,我有点忘记这道题目的思路了
话说唯一分解好像可以写成$\sqrt(n)$的吧
为什么不直接用求和公式加上求逆元
我是按照yxc老师的方法做的.
因为公式是(p^(n + 1) - 1)/(p - 1)
又因为要模9901所以在有一个点时,p^(n + 1) % 9901 = 1, 再减1是0,就错了
这个点是59407 3
交到poj上会t掉
能不能把POJ这道题目的网址发我一下,我去康康,有什么区别.按理说我这道题目代码不会TLE.
http://poj.org/problem?id=1845
感谢已经修改完毕.
请问
if(c&1) 不就直接判断为奇数吗
是的啊,这样写速度快
为什么偶数要加+ksm(p,c)
次数是奇数但是数因为还有个零次幂的关系会是偶数个数,所以后面要加一下
用等比数列求和公式+对分母求逆元应该更快,二分求和为logn*logn,快速幂求逆元为logn
ORZ
zbnb
’‘’
return ((1+ksm(p,(c+1)>>1))sum(p,(c-1)>>1))%Mod;//奇数的情况下
else
return ((1+ksm(p,c>>1))sum(p,(c>>1)-1)+ksm(p,c))%Mod;//偶数的情况下
‘’‘
在递归的过程中取模了无数次,但是按题目是smod9901,只取模了一次,为什么递归过程得到的结果是正确的?
这是可以的,因为取模运算是传递的啊.
而且你过程中如果不取模,那么你就会WA,除非你是高精度.
比如说,a%9901b和ab%9901是一样的
吼的,谢谢(ง •_•)ง