发布于2021-03-13 18:14 阅读(791) 评论(0) 点赞(9) 收藏(2)
假设现在有两个自然数 A 和 B,S 是 AB 的所有约数之和。
请你求出 Smod9901 的值是多少。
输入格式
在一行中输入用空格隔开的两个整数 A 和 B。
输出格式
输出一个整数,代表 Smod9901 的值。
数据范围
0≤A,B≤5×107
输入样例:
2 3
输出样例:
15
注意: A 和 B 不会同时为 0。
我们在算法基础课的时候学过如何求一个数的公约数之和。
利用这个性质我自己写了一个代码。
#include<iostream>
#include<map>
#include<algorithm>
using namespace std;
const int MOD=9901;
int main(void)
{
unordered_map<int,int> hash;
int a,b;
cin>>a>>b;
for(int i=2;i<=a/i;i++)
{
while(a%i==0)
{
hash[i]++;
a/=i;
}
}
if(a>1)
hash[a]++;
long long res=1;
for(auto t:hash)
{
long long p=1;
for(int i=1;i<=t.second*b;i++)
{
p=((long long)p*t.first+1)%MOD;
}
res=(long long)res*p%MOD;
}
cout<<res<<endl;
}
但是很遗憾,居然没有过????
然后我无奈,只好看看有没有更好的算法,然后看了y总的视频
知道了用递归实现一个二分之类的状态
我觉得这个方法很巧妙,不过我不太理解为什么y总给的是1-k-1的版本的,我用1-k版本的确实会有一些bug在k+1/2上
代码如下:
#include<iostream>
#include<map>
#include<algorithm>
using namespace std;
typedef long long LL;
const int MOD=9901;
int quickpow(int a,int b)
{
int res=1;
a%=MOD;
while(b)
{
if(b&1) res=(LL)res*a%MOD;
a=(LL)a*a%MOD;
b>>=1;
}
return res;
}
int sum(int p,int k)
{
if(k==1)
return 1;
if(k%2==0)
return (LL)(1+quickpow(p,k/2))*sum(p,k/2)%MOD;
else
return (quickpow(p,k-1)+sum(p,k-1))%MOD;
}
int main(void)
{
int a,b;
cin>>a>>b;
int res=1;
for(int i=2;i*i<=a;i++)
{
int d=0;
while(a%i==0)
{
d++;
a/=i;
}
if(d)
res=(LL)res*sum(i,b*d+1)%MOD;
}
// exit(0);
if(a>1)
res=(LL)res*sum(a,b+1)%MOD;
else if(a==0)
res=0;
cout<<res<<endl;
}
原文链接:https://blog.csdn.net/qq_52358098/article/details/114703613
作者:爱出汗
链接:http://www.qianduanheidong.com/blog/article/35708/57a10682d6d44684fa7e/
来源:前端黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 前端黑洞网 All Rights Reserved 版权所有,并保留所有权利。 京ICP备18063182号-3
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!