(题面来自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,把所求因数和因式分解为每个质因数的若干次幂等比求和相乘的形式后,分治递归求出每一个等比数列的和。

代码:

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <cstring>
  4. #include <cstdio>
  5. using namespace std;
  6. const int mod(9901), msqrt(7100), maxn(50000000);
  7. int A, B;
  8. int prime[msqrt];
  9. bool vis[msqrt];
  10. void euler() {  //欧拉筛
  11. for (int i = 2; i <= msqrt; ++i) {
  12. if (!vis[i])
  13. prime[++prime[0]] = i;
  14. for (int j = 1; j <= prime[0] && prime[j] * i <= msqrt; ++j) {
  15. vis[prime[j] * i] = true;
  16. if (i % prime[j] == 0)
  17. break;
  18. }
  19. }
  20. /*  int t = 1;
  21. for (int i = 1; i <= prime[0]; ++i) { //暴力确定质因数的最多个数
  22. t *= prime[i];
  23. if (t > maxn) {
  24. cout << i << " " << t;
  25. break;
  26. }
  27. }*/
  28. }
  29. int fc[20][2], top;
  30. void Get_factors(int x, const int &B) {  //质因数分解
  31. for (int i = 1; i <= prime[0] && x; ++i)
  32. if (x % prime[i] == 0) {
  33. fc[++top][0] = prime[i];
  34. while (x % prime[i] == 0)
  35. ++fc[top][1], x /= prime[i];
  36. fc[top][1] *= B;
  37. }
  38. if (x > 1)//A is a big prime
  39. fc[++top][0] = x, fc[top][1] = B;
  40. }
  41. int ans = 1;
  42. int fpow(int a, int b) {
  43. int ret = 1;
  44. while (b) {
  45. if (b & 1)
  46. ret = ret * a % mod;
  47. b >>= 1;
  48. a = a * a % mod;
  49. }
  50. return ret;
  51. }
  52. int calc(int a, int b) {  //计算各等比数列之和
  53. if (b == 0) return 1;
  54. if (b & 1)
  55. return (1 + fpow(a, (b + 1) >> 1)) * calc(a, b >> 1) % mod;
  56. return (1 + a * calc(a, b - 1)) % mod;
  57. }
  58. int main() {
  59. cin >> A >> B;
  60. if (A == 0) {  //特判
  61. putchar('0');
  62. return 0;
  63. }
  64. euler();
  65. Get_factors(A, B);
  66. for (int i = 1; i <= top; ++i)
  67. ans = (ans * calc(fc[i][0] % mod, fc[i][1])) % mod;
  68. cout << ans;
  69. return 0;
  70. }

【POJ 1845】Sumdiv——数论 质因数 + 分治 + 快速幂的更多相关文章

  1. poj 1845 Sumdiv (数论)

    题目链接 题意:求 A^B的所有约数之和对9901取模后的结果. 分析: 看了小优的博客写的. 分析来自 http://blog.csdn.net/lyy289065406/article/detai ...

  2. poj 1845 POJ 1845 Sumdiv 数学模板

    筛选法+求一个整数的分解+快速模幂运算+递归求计算1+p+p^2+````+p^nPOJ 1845 Sumdiv求A^B的所有约数之和%9901 */#include<stdio.h>#i ...

  3. poj 2888 Magic Bracelet(Polya+矩阵快速幂)

    Magic Bracelet Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 4990   Accepted: 1610 D ...

  4. 【BZOJ4002】[JLOI2015]有意义的字符串(数论,矩阵快速幂)

    [BZOJ4002][JLOI2015]有意义的字符串(数论,矩阵快速幂) 题面 BZOJ 洛谷 题解 发现我这种题总是做不动... 令\(A=\frac{b+\sqrt d}{2},B=\frac{ ...

  5. 【BZOJ2432】【NOI2011】兔农(数论,矩阵快速幂)

    [BZOJ2432][NOI2011]兔农(数论,矩阵快速幂) 题面 BZOJ 题解 这题\(75\)分就是送的,我什么都不想写. 先手玩一下,发现每次每次出现\(mod\ K=1\)的数之后 把它减 ...

  6. POJ 1845 Sumdiv [素数分解 快速幂取模 二分求和等比数列]

    传送门:http://poj.org/problem?id=1845 大致题意: 求A^B的所有约数(即因子)之和,并对其取模 9901再输出. 解题基础: 1) 整数的唯一分解定理: 任意正整数都有 ...

  7. POJ 1845 Sumdiv (整数拆分+等比快速求和)

    当我们拆分完数据以后, A^B的所有约数之和为: sum = [1+p1+p1^2+...+p1^(a1*B)] * [1+p2+p2^2+...+p2^(a2*B)] *...*[1+pn+pn^2 ...

  8. poj 1845 【数论:逆元,二分(乘法),拓展欧几里得,费马小定理】

    POJ 1845 题意不说了,网上一大堆.此题做了一天,必须要整理一下了. 刚开始用费马小定理做,WA.(poj敢说我代码WA???)(以下代码其实都不严谨,按照数据要求A是可以等于0的,那么结果自然 ...

  9. POJ 1845 Sumdiv

    快速幂+等比数列求和.... Sumdiv Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 12599 Accepted: 305 ...

随机推荐

  1. 【问题记录】—.NetCore 编译问题

    最近在协助验证Jenkins自动编译发布时,对一些.Net Core编译问题进行了解决:特记录一下 一.编译生成netcoreapp目录问题 问题现象 .net core项目编译输出目录总是包含在[n ...

  2. redis简介以及redis集群配置

    简介: redis 是一个高性能的key-value数据库..它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set --有序 ...

  3. 合适的LoRa网关应该怎么选择

    LoRa网关是什么 LoRa网关有时也被称之为lora基站或者lora集中器,它在lora星形组网中处于核心位置,是数据终端和服务器之间的一个信息桥梁.LoRa网关使用的是不同扩频因子,因为不同的扩频 ...

  4. 【Flutter 混合开发】添加 Flutter 到 iOS

    Flutter 混合开发系列 包含如下: 嵌入原生View-Android 嵌入原生View-iOS 与原生通信-MethodChannel 与原生通信-BasicMessageChannel 与原生 ...

  5. python机器学习识别手写数字

    手写数字识别 关注公众号"轻松学编程"了解更多. 导包 import numpy as np import matplotlib.pyplot as plt %matplotlib ...

  6. 利用远程桌面管理winserver集群

    在适用mstsc连接winserver服务器的场景下(别问为什么不VNC),可以利用rdp文件等方式减轻连接的操作负担 利用.rdp文件免密登录 rdp文件本质上是一个mstsc的选择,或者不如说ms ...

  7. php随机填充字符串内容

    public function getStr($str=false){ $poems="从,善,如,登,从,恶,如,崩,已,知,花,意,未,见,其,花,,,已,见,其,花,,,未,闻,花,名 ...

  8. fork 子进程,父进程对于变量的共享

    经过代码的练习发现: fork创建的子进程会完全复制父进程的代码包括变量,既复制fork之前创建的变量. 但是在创建子进程后,子进程与父进程对同一个变量的改变将相互不受影响,即使获取同一变量的地址是一 ...

  9. 记在Linux上定位后台服务偶发崩溃的问题

    问题描述 在最近的后台服务中,新增将某个指令的请求数据落盘保存的功能.在具体实现时,采用成员变量来保存请求消息代理头,在接收响应以及消息管理类释放时进行销毁.测试反馈,该服务偶发崩溃. 问题分析 测试 ...

  10. python之 《zip,lambda, map》

    1.zip 对于zip我们一般都是用在矩阵上 eg: a = [1,2,3] b = ['a', 'b', 'c'] x = zip(a, b) print(x) print(list(x)) 结果是 ...