约数之和(POJ1845 Sumdiv)
最近应老延的要求再刷《算法进阶指南》(不得不说这本书不错)...这道题花费了较长时间~(当然也因为我太弱了)所以就写个比较易懂的题解啦~
原题链接:POJ1845
翻译版题目(其实是AcWing上的):
假设现在有两个自然数A和B,S是AB的所有约数之和。
请你求出S mod 9901的值是多少。
输入格式
在一行中输入用空格隔开的两个整数A和B。
输出格式
输出一个整数,代表S mod 9901的值。
数据范围
0≤A,B≤5×107
输入样例:
2 3
输出样例:
15
注意: A和B不会同时为0。
首先看到这题就知道不能打暴力(这还用你说),那就需要找一个巧方法
那么,什么是约数呢?
约数嘛,顾名思义,可以约掉的数,其实就是因数
如果你连因数都不知道就只好自行百度了
但其实百度还挺有用的
以下是约数的定义:
约数,又称因数。整数a除以整数b(b≠0) 除得的商正好是整数而没有余数,我们就说a能被b整除,或b能整除a。a称为b的倍数,b称为a的约数。在大学之前,"约数"一词所指的一般只限于正约数。约数和倍数都是二元关系的概念,不能孤立地说某个整数是约数或倍数。一个整数的约数是有限的。同时,它可以在特定情况下成为公约数。
但你再往下翻你会找到这个东西:

恩?这不就是质因数分解吗?
根据这个思路,我们很容易得到以下结论:
若A=P1c1*P2c2*...*Pncn ,那么AB就等于
P1B*c1*P2B*c2*...*PnB*cn
又因为AB的约数集合可以看做其每一个质因数分别相乘得出的结果的集合
举个例子便于理解:
12=22*31
所以12的因数集合为
{1,2,3,2*2,2*3,2*2*3}={1,2,3,4,6,12}
可以看做把12的质因数分别组合相乘
那么我们把这个式子加起来可以得到
1+2+3+2*2+2*3+2*2*3
稍微改造一下
(1+2+2*2)(1+3)
似乎有点眉目了?
那么AB的约数之和由此可得:
(1+P1+P12+....+P1B*c1)*(1+P2+P22+....+P2B*c2)*....*(1+Pn+Pn2+....+PnB*cn)
(这段真他喵的难打)
根据同余定理,我们在求AB%9901就相当于以上每一个式子%9901再相乘
那么问题就又到了如何求(1+P+P2+....+Pc)
因为同余对于除法没有分配率,所以这道题不能使用等比数列求和公式....
所以这时候我们想到了.....
分治!
将求解(1+P+P2+....+Pc)定义为sum(p,c),则有:
当c为奇数时:
sum(p,c)=(1+P+....+P(c-1)/2)+(1+P(c+1)/2+...+Pc)
int m=;
for(int i=;i<=sqrt(n);i++)
{
if(n%i==)
m++,yz[m]=i;//yz数组存分解出的因子
while(n%i==)//除掉所有的i
{
n/=i;
gs[m]++;//gs数组存每个因子的个数
}
}
if(n>)
m++,yz[m]=n,gs[m]=;
for(int i=;i<=m;i++)
printf("%d^%d\n",yz[i],gs[i]);
还有一种更优的算法,叫做“Pollard's Rho”算法,但有点复杂(我懒得写),可以自行去查 已经帮你查好了←
那么这道题就可以写出来了~(我相信你会快速幂)
以下AC代码
#include<cmath>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
using namespace std;
const int N=;
int yz[],gs[];//分别用来存储质因子及其个数
int quick(int a,int b)//快速幂
{
long long t;
if(b==)return a%N;
if(b%==)
{
t=quick(a,b/);
return t%N*t%N;
}
else
{
t=quick(a,b/);
t=t%N*t%N;
t=t%N*a%N;
return t%N;
}
}
long long sum(int p,int c)
{
if(c==) return ;//边界
if(c==) return p+;//边界*2,可写可不写,开始没加1出了点问题
if(c%)
return (+quick(p,(c+)/))%N*sum(p,c/)%N;//奇数
else
return (+quick(p,c/))%N*sum(p,c/-)%N+quick(p,c);//偶数
}
long long czs(int n,int b)//分解质因数
{
if(n==) return ;//特殊情况直接返回
if(b==) return ;
int m=,ans=;
for(int i=;i<=sqrt(n);i++)
{
if(n%i==)
m++,yz[m]=i;
while(n%i==)
{
n/=i;
gs[m]++;
}
}
if(n>)
m++,yz[m]=n,gs[m]=;
for(int i=;i<=m;i++)
ans=(ans%N*sum(yz[i],gs[i]*b)%N)%N;
return ans%N;
}
int main()
{
int a,b;
scanf("%d%d",&a,&b);
printf("%lld",czs(a,b)%N);
return ;
}
//写这么多%N是因为数据溢出www
//那个数据在下方,可以试一试能不能过
//输入:50000000 50000000
//输出:5531
终于完了 赶紧刷B站学习去了
感谢观看~ヽ( ̄▽ ̄)ノ
约数之和(POJ1845 Sumdiv)的更多相关文章
- 【题解】POJ1845 Sumdiv(乘法逆元+约数和)
POJ1845:http://poj.org/problem?id=1845 思路: AB可以表示成多个质数的幂相乘的形式:AB=(a1n1)*(a2n2)* ...*(amnm) 根据算数基本定理可 ...
- poj1845 Sumdiv
poj1845 Sumdiv 数学题 令人痛苦van分的数学题! 题意:求a^b的所有约数(包括1和它本身)之和%9901 这怎么做呀!!! 百度:约数和定理,会发现 p1^a1 * p2^a2 * ...
- POJ1845Sumdiv题解--约数之和
题目链接 https://cn.vjudge.net/problem/POJ-1845 分析 \(POJ\)里的数学题总是这么妙啊 首先有一个结论就是\(A=\prod{ \ {p_i}^{c_i} ...
- POJ1845 Sumdiv(求所有因数和+矩阵快速幂)
题目问$A^B$的所有因数和. 根据唯一分解定理将A进行因式分解可得:A = p1^a1 * p2^a2 * p3^a3 * pn^an.A^B=p1^(a1*B)*p2^(a2*B)*...*pn^ ...
- 51NOD 1220 约数之和 [杜教筛]
1220 约数之和 题意:求\(\sum_{i=1}^n \sum_{j=1}^n \sigma_1(ij)\) \[ \sigma_0(ij) = \sum_{x\mid i}\sum_{y\mi ...
- POJ1845 sumdiv 数论
正解:小学数学数论 解题报告: 传送门! 其实不难但我数学这个方面太菜了所以还是多写点儿博客趴QAQ 然后因为是英文的所以先翻译一下,,,? 大概就是说求AB的所有约数之和,对9901取膜 这个只需要 ...
- 【动态规划】mr359-最大公约数之和
[题目大意] 选取和不超过S的若干个不同的正整数,使得所有数的约数(不含它本身)之和最大. 输入一个正整数S. 输出最大的约数之和. 样例输入 Sample Input 11 样例输出 Sample ...
- POJ1845 Sumdiv 数学?逆元?
当初写过一篇分治的 题意:求A^B的所有因子之和,并对其取模 9901再输出 对于数A=p1^c1+p2^c2+...+pn*cn,它的所有约数之和为(1+p1+p1^2+p1^3+...+p1^(c ...
- 51Nod 约数之和
1220 约数之和 题目来源: Project Euler 基准时间限制:3 秒 ...
随机推荐
- 阿里云ECS搭建kubernetes1.11
环境信息 说明 1.使用kubeadm安装集群 虚拟机信息 hostname memory cpu disk role node1.com 4G 2C vda20G vdb20G master nod ...
- Relation-Shape Convolutional Neural Network for Point Cloud Analysis(CVPR 2019)
代码:https://github.com/Yochengliu/Relation-Shape-CNN 文章:https://arxiv.org/abs/1904.07601 作者直播:https:/ ...
- Photoshop CS2软件下载与安装教程
Photoshop CS2精简版下载地址: 链接:https://pan.baidu.com/s/1ryJPLuKG_MixWjGJgLebOg提取码:nzz9 软件介绍: Photoshop主要处理 ...
- JVM系列一(Java内存区域和对象创建).
一.JVM 内存区域 堆 - Heap 线程共享,JVM中最大的一块内存,此内存的唯一目的就是存放对象实例,Java 堆是垃圾收集器管理的主要区域,因此很多时候也被称为"GC堆"( ...
- 1sql
------------------ MySQL 服务-- sudo service mysql start/stop/restart/status ------------------ 数据库相关的 ...
- nginx的使用,以及反向代理,负载均衡,从安装到使用,全部步骤。
先总结nginx实现负载均衡的原理,在这之前先的知道反向代理,因为nginx的负载均衡是在反向代理的基础上实现的: 1.反向代理:通过在nginx的配置文件 (vim /opt/nginx196/co ...
- linux防火墙的相关命令
一.iptables防火墙(需要安装防火墙sudo apt-get install firewalld命令查看插件)1.基本操作 # 查看防火墙状态 service iptables status # ...
- golang实现rabbitmq消息队列失败尝试
在工作中发现,有些时候消息因为某些原因在消费一次后,如果消息失败,这时候不ack,消息就回一直重回队列首部,造成消息拥堵. 如是有了如下思路: 消息进入队列前,header默认有参数 retry_nu ...
- Djangoday2第二个app加减法
第二个app 计算新建一个app在view定义显示的内容修改urls指定连接对应的视图测试另一种通过路径传参的方式访问网址路径传参的urls定义方法网址路径传参测试urls的urlnamedjango ...
- js如何衔接css3的多个@keyframes动画?
css3特效动画,我们在编写页面中经常遇到,而且是在同一个div模块上有多个衔接的不同动画,css中,我们经常使用animation-delay (规定在动画开始之前的延迟)进行处理. 那么,下面分享 ...