题目:

POJ1845

分析:

首先用线性筛把\(A\)分解质因数,得到:

\[A=p_1^{a_1}*p_2^{a_2}...*p_n^{a_n} (p_i是质数且a_i>0)
\]

则显然\(A^B\)分解质因数后为

\[A=p_1^{a_1B}*p_2^{a_2B}...*p_n^{a_nB} (p_i是质数且a_i>0)
\]

接下来隆重推出约数和定理:(证明见【知识总结】约数个数定理和约数和定理及其证明)

\[Sum=\prod_{i=1}^n \sum_{j=0}^{a_i}p_i^j
\]

那么很明显可以对于每一个\(p_i\)计算\(p_i^0+p_i^1...+p_1^{a_iB}\)然后乘起来就是答案。这就是一个等比数列求和了。

等比数列求和公式中含有除法,所以取模求和的时候不能直接用求和公式,否则如果除数刚好是模数的倍数就会出现逆元不存在的尴尬情况……例如POJ该题讨论区中的数据\(59407 \ 1\) (\(59407=9901*6+1\),求和公式中除数是\(59406\),此数在模\(9901\)意义下没有逆元)

这里介绍一种二分等比数列求和的方法,思路和快速幂相似,即代码中的\(powersum\)函数

可以把这个等比数列平分成长度相等的两部分。

当\(n\)是偶数

\[(p_i^0+p_i^1...+p_i^{n/2})+(p_i^{n/2+1}+p_i^{n/2+2}...+p_i^n)
\]

然后从后半部分提出一个\(p_i^{n/2+1}\),它就和偶数部分一样了!得到

\[(p_i^0+p_i^1...+p_i^{n/2})*(p_i^{n/2+1}+1)
\]

显然左边可以递归地算下去,右边用快速幂求出。

当\(n\)是奇数,只要上述\(n/2\)均向下取整,算完以后加上\(p_i^n\)就可以了。这个也可以用快速幂解决。

代码:

\(powersum\)函数求的是\(\sum_{j=1}^{a_i}p_i^j\),所以最后统计答案的时候要手动加上\(p_i^0\) (也就是\(1\))

筛质数时有一个小技巧。并不需要筛出\(5e7\)范围内的所有质数。x不可能含有两个或以上大于\(\sqrt x\)的质因数,所以\(x\)除以\(\sqrt{5e7}\)范围内的所有质数后如果仍不为\(1\),那么此时剩下的\(x\)一定是一个质数

我才不会告诉你模数叫QQ_kotori是为了膜某位n姓QQ小嘴/复读机

#include <iostream>
using namespace std; namespace zyt
{
typedef long long ll;
const int QQ_kotori = 9901;
const int M = 7100;
ll prime[M], index[M];
int cnt;
void init_prime(ll x)
{
static bool mark[M];
for (int i = 2; i < M && x > 1; i++)
{
if (!mark[i])
{
ll tmp = 0;
prime[cnt] = i;
while (x % i == 0)
tmp++, x /= i;
index[cnt++] = tmp;
}
for (int j = 0; j < cnt && i * prime[j] < M; j++)
{
ll k = i * prime[j];
mark[k] = true;
if (i % prime[j] == 0)
break;
}
}
if (x > 1)
{
prime[cnt] = x;
index[cnt++] = 1;
}
}
ll power(ll a, ll b)
{
ll ans = 1;
while (b)
{
if (b % 2)
ans = ans * a % QQ_kotori;
a = a * a % QQ_kotori;
b /= 2;
}
return ans;
}
ll powersum(ll a, ll b)
{
if (b == 1)
return a % QQ_kotori;
ll ans = powersum(a, b / 2) * (1 + power(a, b / 2)) % QQ_kotori;
if(b % 2)
ans = (ans + power(a, b)) % QQ_kotori;
return ans;
}
void work()
{
ll a, b, ans = 1;
cin >> a >> b;
if (a == 0)
{
cout << 0;
return;
}
else if (b == 0)
{
cout << 1;
return;
}
init_prime(a);
for (int i = 0; i < cnt; i++)
if (index[i])
ans = ans * (powersum(prime[i], index[i] * b) + 1) % QQ_kotori;
cout << ans;
}
}
int main()
{
zyt::work();
return 0;
}

【POJ1845】Sumdiv(数论/约数和定理/等比数列二分求和)的更多相关文章

  1. HDU1588-Gauss Fibonacci(矩阵高速幂+等比数列二分求和)

    题目链接 题意:g(x) = k * x + b.f(x) 为Fibonacci数列.求f(g(x)),从x = 1到n的数字之和sum.并对m取模. 思路:  设A = |(1, 1),(1, 0) ...

  2. POJ1845 Sumdiv [数论,逆元]

    题目传送门 Sumdiv Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 26041   Accepted: 6430 Des ...

  3. POJ1845 sumdiv 数论

    正解:小学数学数论 解题报告: 传送门! 其实不难但我数学这个方面太菜了所以还是多写点儿博客趴QAQ 然后因为是英文的所以先翻译一下,,,? 大概就是说求AB的所有约数之和,对9901取膜 这个只需要 ...

  4. 题解 poj1845 Sumdiv (数论) (分治)

    传送门 大意:求A^B的所有因子之和,并对其取模 9901再输出 (这题又调了半天,把n和项数弄混了QAQ) 根据算数基本定理:A=(p1^k1)*(p2^k2)*(p3^k3)*...*(pn^kn ...

  5. 等比数列二分求和(logn复杂度)

    看完这个之后,感觉数学简直太厉害了 转载自:http://blog.csdn.net/acdreamers/article/details/7851144 今天我们学习如何有效地求表达式的值.对于这个 ...

  6. poj 1845 Sumdiv 约数和定理

    Sumdiv 题目连接: http://poj.org/problem?id=1845 Description Consider two natural numbers A and B. Let S ...

  7. 【FZYZOJ】数论课堂 题解(约数个数定理)

    前言:想了两个小时orz,最后才想到要用约数个数定理…… ------------- 题目大意: 给定$n,q,A[1],A[2],A[3]$ 现有$A[i]=(A[i-1]+A[i-2]+A[i-3 ...

  8. poj1845 Sumdiv

    poj1845 Sumdiv 数学题 令人痛苦van分的数学题! 题意:求a^b的所有约数(包括1和它本身)之和%9901 这怎么做呀!!! 百度:约数和定理,会发现 p1^a1 * p2^a2 * ...

  9. poj 1845 Sumdiv (数论)

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

随机推荐

  1. apache 添加虚拟机

    <VirtualHost *:80> DocumentRoot "E:/UPUPW_AP7.0/htdocs/xd.local/public" ServerName a ...

  2. 1.Ubuntu查看Python版本

    1.输入命令:ls -l /usr/bin/python*

  3. Codeforces 263A. Appleman and Easy Task

    A. Appleman and Easy Task time limit per test  1 second memory limit per test  256 megabytes input  ...

  4. Codeforces 158B (数学)

    B. Mushroom Scientists time limit per test 2 seconds memory limit per test 256 megabytes input stand ...

  5. mybatis指定jdbctype

    MyBatis 插入空值时,需要指定JdbcType mybatis insert空值报空值异常,但是在pl/sql不会提示错误,主要原因是mybatis无法进行转换 所以在MyBatis映射文件中要 ...

  6. gradle: 修改gradle-xx-bin.zip下载地址

    进入gradle/wrapper/目录,修改gradle-wrapper.properties文件, 将distributionUrl修改为自己的下载地址即可. 另外修改gradle reposito ...

  7. Redis是单线程的

    Redis是单线程的 学习了: http://blog.csdn.net/liupeng_qwert/article/details/77263187 https://www.cnblogs.com/ ...

  8. Windows 如何在右键中添加“在此处打开CMD窗口”选项

    将以下代码保存为XXX.reg,然后双击导入注册表 Windows Registry Editor Version 5.00   [HKEY_CLASSES_ROOT\Directory\shell\ ...

  9. C++成员对齐方式探讨

    本文參考了<高质量程序设计指南--C++/C语言>一书 有不妥之处恳请指正 一.自然对齐 某些基于RISC(精简指令集)的CPU比方SPARC.PowerPC等.採用高字节和高字在低地址存 ...

  10. 负载均衡算法,轮询方式 大话设计模式之工厂模式 C#

    负载均衡算法,轮询方式 2018-04-13 17:37 by 天才卧龙, 13 阅读, 0 评论, 收藏, 编辑 学无止境,精益求精 十年河东,十年河西,莫欺少年穷 学历代表你的过去,能力代表你的现 ...