约数之和(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 秒 ...
随机推荐
- Java基础知识总结之类的集合
Java集合概述 1.集合类也叫作容器类.它的功能相当于一个容器.可以存储数量不确定的数据,以及保存具有映射关系的数据(也被称为关联数组). 2.Java的集合(容器),它是用来”装对象的“(实际上是 ...
- TypeError: Cannot read property '_t' of undefined (VUE + ElementUI + i18n)
在使用vue的ElementUI库,在多语言时报错: TypeError: Cannot read property '_t' of undefined 错误是在点菜单栏时随机抛出的,F12抓不到,只 ...
- 2019-10-16:渗透测试,基础学习,burpsuit笔记
maccms10后门分析下载网址,是假官网http://www.maccmsv10.com/download.htmlMaccms10基于php+mysql的maccms,是苹果的内容管理,方便使用, ...
- Ajax与Http协议
目录 Ajax与Http协议详解 Xhr对象 xhr对象发送请求整体感知 xhr对象的常用属性和方法 xhr对象发送post请求 xhr对象的兼容性问题 请求超时timeout与监听超时ontimeo ...
- linux bash编程之函数和循环控制
函数:实现独立功能的代码段 函数只有在调用时才会执行 语法一: function F_NAME{ 函数体 } 语法二: F_NAME() { 函数体 } 函数的返回值: 默认函数返回值:函数执行状态返 ...
- 音频工具kaldi部署及模型制作调研学习
语音识别简介 语音识别(speech recognition)技术,也被称为自动语音识别(英语:Automatic Speech Recognition, ASR).计算机语音识别(英语:Comput ...
- Mybatis分页插件PageHelper的学习与使用
目录 中文教程 PageHelper使用 后端程序员都知道,在Web系统中,分页是一种常见的功能,我之前写的分页方法都比较麻烦,移植性也不高,这就很不乐观了.作为一个积极开朗的程序员,怎么能不去了解P ...
- PHP页面跳转三种实现方法
一.header()函数 header()函数是PHP中进行页面跳转的一种十分简单的方法.header()函数的主要功能是将HTTP协议标头(header)输出到浏览器.header()函数的定义如下 ...
- 使用Navicat连接阿里云服务器中的Mysql数据库
1.首先将阿里云服务器中的安全组添加上Mysql的端口3306,如下图所示: 步骤就是进入到阿里云的官网,点击右上角控制台,在左边选择云服务器ECS--->实例 点击图中的管理按钮,然后选择本实 ...
- 能不能自己写个类,也叫java.lang.String?
可以,但在应用的时候,需要用自己的类加载器去加载,否则,系统的类加载器永远只是去加载jre.jar包中的那个java.lang.String.由于在tomcat的web应用程序中,都是由webapp自 ...