【POJ 1845】Sumdiv——数论 质因数 + 分治 + 快速幂
(题面来自luogu)
题目描述
输入两个正整数a和b,求a^b的所有因子之和。结果太大,只要输出它对9901的余数。
输入格式
仅一行,为两个正整数a和b(0≤a,b≤50000000)。
输出格式
a^b的因子和对9901的余数。
题中给出的数据很大,暴力明显不可取。顺着题目的思路,我们需要表示出a^b的所有约数之和。考虑把a质因数分解,则原式可以表示为:

那么上式的所有因数就是它的质因数的组合相乘构成的集合。令它们求和,可以发现,和式可以因式分解后表示为

这个式子把所求的答案表示成了若干和式相乘的形式,可以较为方便的进行取模。而前9个质数之积已经超过了给定范围,原式的乘数不会很多,因此把每个和式的答案算出来暴力相乘即可。
观察发现每个和式都是等比数列求和的形式;如果直接套用公式,需要做除法,可以使用费马小定理求出每个除数的逆元来做。因为我觉得逆元很麻烦,这里依照算法进阶的思路,使用分治在log^2的复杂度内求出每个和式的结果。当ci * b为奇数时:

这个式子每进行一次分解,和式的项数就会缩小一半,很适合进行分治计算;式中提出的p的幂可以用快速幂来算出。当ci * b是偶数时,可以提出一个p来变为奇数处理。那么等比数列求和也可以在可承受的复杂度内解决了。
本题的总体思路:质因数分解a^b,把所求因数和因式分解为每个质因数的若干次幂等比求和相乘的形式后,分治递归求出每一个等比数列的和。
代码:
- #include <iostream>
- #include <algorithm>
- #include <cstring>
- #include <cstdio>
- using namespace std;
- const int mod(9901), msqrt(7100), maxn(50000000);
- int A, B;
- int prime[msqrt];
- bool vis[msqrt];
- void euler() { //欧拉筛
- for (int i = 2; i <= msqrt; ++i) {
- if (!vis[i])
- prime[++prime[0]] = i;
- for (int j = 1; j <= prime[0] && prime[j] * i <= msqrt; ++j) {
- vis[prime[j] * i] = true;
- if (i % prime[j] == 0)
- break;
- }
- }
- /* int t = 1;
- for (int i = 1; i <= prime[0]; ++i) { //暴力确定质因数的最多个数
- t *= prime[i];
- if (t > maxn) {
- cout << i << " " << t;
- break;
- }
- }*/
- }
- int fc[20][2], top;
- void Get_factors(int x, const int &B) { //质因数分解
- for (int i = 1; i <= prime[0] && x; ++i)
- if (x % prime[i] == 0) {
- fc[++top][0] = prime[i];
- while (x % prime[i] == 0)
- ++fc[top][1], x /= prime[i];
- fc[top][1] *= B;
- }
- if (x > 1)//A is a big prime
- fc[++top][0] = x, fc[top][1] = B;
- }
- int ans = 1;
- int fpow(int a, int b) {
- int ret = 1;
- while (b) {
- if (b & 1)
- ret = ret * a % mod;
- b >>= 1;
- a = a * a % mod;
- }
- return ret;
- }
- int calc(int a, int b) { //计算各等比数列之和
- if (b == 0) return 1;
- if (b & 1)
- return (1 + fpow(a, (b + 1) >> 1)) * calc(a, b >> 1) % mod;
- return (1 + a * calc(a, b - 1)) % mod;
- }
- int main() {
- cin >> A >> B;
- if (A == 0) { //特判
- putchar('0');
- return 0;
- }
- euler();
- Get_factors(A, B);
- for (int i = 1; i <= top; ++i)
- ans = (ans * calc(fc[i][0] % mod, fc[i][1])) % mod;
- cout << ans;
- return 0;
- }
【POJ 1845】Sumdiv——数论 质因数 + 分治 + 快速幂的更多相关文章
- poj 1845 Sumdiv (数论)
题目链接 题意:求 A^B的所有约数之和对9901取模后的结果. 分析: 看了小优的博客写的. 分析来自 http://blog.csdn.net/lyy289065406/article/detai ...
- poj 1845 POJ 1845 Sumdiv 数学模板
筛选法+求一个整数的分解+快速模幂运算+递归求计算1+p+p^2+````+p^nPOJ 1845 Sumdiv求A^B的所有约数之和%9901 */#include<stdio.h>#i ...
- poj 2888 Magic Bracelet(Polya+矩阵快速幂)
Magic Bracelet Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 4990 Accepted: 1610 D ...
- 【BZOJ4002】[JLOI2015]有意义的字符串(数论,矩阵快速幂)
[BZOJ4002][JLOI2015]有意义的字符串(数论,矩阵快速幂) 题面 BZOJ 洛谷 题解 发现我这种题总是做不动... 令\(A=\frac{b+\sqrt d}{2},B=\frac{ ...
- 【BZOJ2432】【NOI2011】兔农(数论,矩阵快速幂)
[BZOJ2432][NOI2011]兔农(数论,矩阵快速幂) 题面 BZOJ 题解 这题\(75\)分就是送的,我什么都不想写. 先手玩一下,发现每次每次出现\(mod\ K=1\)的数之后 把它减 ...
- POJ 1845 Sumdiv [素数分解 快速幂取模 二分求和等比数列]
传送门:http://poj.org/problem?id=1845 大致题意: 求A^B的所有约数(即因子)之和,并对其取模 9901再输出. 解题基础: 1) 整数的唯一分解定理: 任意正整数都有 ...
- POJ 1845 Sumdiv (整数拆分+等比快速求和)
当我们拆分完数据以后, A^B的所有约数之和为: sum = [1+p1+p1^2+...+p1^(a1*B)] * [1+p2+p2^2+...+p2^(a2*B)] *...*[1+pn+pn^2 ...
- poj 1845 【数论:逆元,二分(乘法),拓展欧几里得,费马小定理】
POJ 1845 题意不说了,网上一大堆.此题做了一天,必须要整理一下了. 刚开始用费马小定理做,WA.(poj敢说我代码WA???)(以下代码其实都不严谨,按照数据要求A是可以等于0的,那么结果自然 ...
- POJ 1845 Sumdiv
快速幂+等比数列求和.... Sumdiv Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 12599 Accepted: 305 ...
随机推荐
- Redis学习笔记(九)——集群
一.概述 Redis Cluster与Redis3.0.0同时发布,以此结束了Redis无官方集群方案的时代. Redis Cluster是去中心化,去中间件,也就是说,集群中的每个节点都是平等的关 ...
- Postman测试数据
一.新增 在controller中编写新增的方法,加上@RequestBody注解,以json格式获取数据 在Postman中,有两种方法新增数据 直接新增参数,如: 以json格式新增 二.删除 根 ...
- 购买GPRS DTU时应该怎么选择
GPRS DTU如今是一种被广泛应用的物联网无线数据终端,主要是利用GPRS网络为用户提供无线长距离数据透传功能,在电力.环保.物流.气象等行业领域有着广泛应用.目前市场上的GPRS DTU产品眼花缭 ...
- TCP连接性能指标之TCP关闭过程(四次挥手)
TCP关闭过程(四次挥手): ESTABLISHED: 当前建立连接状态 CLOSE_WAIT:Server端收到来自Client端的FIN包后,发送ACK回Client端,进入CLOSE_WAIT ...
- 这篇文章揭开python进程、线程、协程神秘的面纱
1.概念 [关注公众号"轻松学编程"了解更多. 回复"协程"获取本文源代码.] 从计算机硬件角度: 计算机的核心是CPU,承担了所有的计算任务. 一个CPU,在 ...
- Django前后端安全验证
会话技术 关注公众号"轻松学编程"了解更多. 1.Cookie 客户端会话技术(数据存储在客户端) 以key-value的形式进行存储 cookie的操作都是通过Response来 ...
- 重要 | Spark和MapReduce的对比,不仅仅是计算模型?
[前言:笔者将分上下篇文章进行阐述Spark和MapReduce的对比,首篇侧重于"宏观"上的对比,更多的是笔者总结的针对"相对于MapReduce我们为什么选择Spar ...
- layui table中固定表头,弹框缩放之后,表头对不齐问题
新手一枚 直接上解决方案 在layui弹出成功后再渲染表格数据 具体操作就是在layer弹层完成之后的回调中渲染表格数据 layer.open({ type: 1, content: $(&quo ...
- 前端搭建本地服务器(Node)
通过Node 去官网下载Node并安装.直通车:http://nodejs.cn/ 安装成功 打开cmd(命令提示符),输入'node-v'检查是否安装成功.下图是安装成功,显示的版本可能会不一样(没 ...
- adb、package及activity
1. adb adb连接手机参考:https://www.cnblogs.com/mind18/p/12592252.html,中的三.5节 1.1. adb介绍 ADB全名Andorid De ...