Sumdiv POJ - 1845 (逆元/分治)
Consider two natural numbers A and B. Let S be the sum of all natural divisors of A^B. Determine S modulo 9901 (the rest of the division of S by 9901).
Input
The only line contains the two natural numbers A and B, (0 <= A,B <= 50000000)separated by blanks.OutputThe only line of the output will contain S modulo 9901.
Sample Input
2 3
Sample Output
15
Hint 2^3 = 8.
The natural divisors of 8 are: 1,2,4,8. Their sum is 15.
15 modulo 9901 is 15 (that should be output).
题意:求AB的所有约数的和 % MOD (9901) 题意中有点问题,我们知道0是没有约数的,我觉得A、B应该都是>0的
思路:我们可以把A分解质因数(p1c1 * p2c2 * .... * pncn)B
约数和:(1 + p1 + p12 + ... + p1B*c1)* (1 + p2 + p22 + ... + p2B*c2)* .... * (1 + pn + pn2 + ... + pnB*cn) ( 排列组合问题)
这样我们可以看出这是多个等比数列乘积,可以用等比数列求和公式 (a1 *(1-qn))/(1-q),我们注意到这里有除法,但是同余模定理是对于加减乘的,那么我们可以利用费马小定理,
求出(1-q)的逆元,然后把除变成乘逆元
坑点:应为 9901 这个质数较小,很容易找到一个数x,(x-1)% MOD == 0 ,就说明这个数是没有逆元的(例217823),那么对于这种情况,我们不能用逆元算,你会发现这种情况下,
pn % MOD == 1 ((p-1)% MOD == 0)),这样(1 + pn + pn2 + ... + pnB*cn) == (1 % MOD + pn %MOD + pn2 %MOD + ... + pnB*cn %MOD) == B*cn+1
#include<iostream>
#include<cstdio>
#include<math.h>
using namespace std; const int maxn = 1e4;
const int mod = ;
int a,b;
int p[maxn];
int c[maxn];
int calc(int x)
{
int m= ;
int up = sqrt(x);
for(int i=;i<=up;i++)
{
if(x % i == )p[++m] = i,c[m] = ;
while(x % i == )x/= i,c[m]++;
}
if(x > )p[++m] = x,c[m] = ;
return m;
} typedef long long ll; ll qpow(ll a,ll b)
{
ll ans = ;
ll base = a;
while(b)
{
if(b&)ans = (ans * base)%mod;
base = (base * base)%mod;
b >>= ;
}
return ans;
}
int main()
{
scanf("%d%d",&a,&b);
int n = calc(a);
ll ans = ;
for(int i=;i<=n;i++)
{
if((-p[i])%mod == )
{
ans = (ans * (b * c[i]+ ))%mod;
continue;
}
ll Ni = qpow(-p[i],mod-);
ll tmp = -qpow(p[i],c[i]*b+);
ans = (ans * (tmp*Ni%mod+mod)%mod)%mod;
}
printf("%lld\n",ans);
}
还有一种写法,就是不用公式计算等比数列和,这样就避免了逆元的问题
sum(p,c) = (1 + p + p2 + ... + pk)
(1)c为奇数,sum(p,k)= sum(p,(k-1 )/2)*(1+p(k+1)/2)
sum(p,c) = (1 + p + p2 + ... + p(k-1)/2)+ (p(k+1)/2 + ... + pk) (c为奇数,加上0次幂,变成偶数,刚好可以分成两个等长的数列)
(2)c为偶数,sum(p,k)= sum(p,k/2-1)*(1+pk/2)+ pk
sum(p,c) = (1 + p + p2 + ... + pk/2-1)+ (pk/2 + ... + pk-1)+ pk (c+1是奇数)
#include<iostream>
#include<cstdio>
#include<math.h>
using namespace std; const int maxn = 1e4;
const int mod = ;
int a,b;
int p[maxn];
int c[maxn];
int calc(int x)
{
int m= ;
for(int i=;i*i<=x;i++)
{
if(x % i == )p[++m] = i,c[m] = ;
while(x % i == )x/= i,c[m]++;
}
if(x > )p[++m] = x,c[m] = ;
return m;
} typedef long long ll;
ll qpow(ll a,ll b)
{
ll ans = ;
ll base = a;
while(b)
{
if(b&)ans = (ans * base)%mod;
base = (base * base)%mod;
b >>= ;
}
return ans;
}
ll sum(ll p,ll c)
{
if(c == )return ;
if(c&)return ((+qpow(p,(c+)/))%mod*(sum(p,(c-)/)%mod))%mod;
else return ((+qpow(p,c/))%mod*(sum(p,c/-))%mod+qpow(p,c))%mod;
} int main()
{
scanf("%d%d",&a,&b);
int n = calc(a);
ll ans = ;
for(int i=;i<=n;i++)
{
ans = (ans * sum(p[i],c[i]*b))%mod;
}
printf("%lld\n",ans);
}
Sumdiv POJ - 1845 (逆元/分治)的更多相关文章
- Sumdiv POJ 1845
http://poj.org/problem?id=1845 题目 Time Limit: 1000MS Memory Limit: 30000K Description Consider two ...
- 洛谷 P1593 因子和 || Sumdiv POJ - 1845
以下弃用 这是一道一样的题(poj1845)的数据 没错,所有宣称直接用逆元/快速幂+费马小定理可做的,都会被hack掉(包括大量题解及AC代码) 什么原因呢?只是因为此题的模数太小了...虽然990 ...
- poj 1845 POJ 1845 Sumdiv 数学模板
筛选法+求一个整数的分解+快速模幂运算+递归求计算1+p+p^2+````+p^nPOJ 1845 Sumdiv求A^B的所有约数之和%9901 */#include<stdio.h>#i ...
- 【POJ 1845】 Sumdiv (整数唯分+约数和公式+二分等比数列前n项和+同余)
[POJ 1845] Sumdiv 用的东西挺全 最主要通过这个题学了约数和公式跟二分求等比数列前n项和 另一种小优化的整数拆分 整数的唯一分解定理: 随意正整数都有且仅仅有一种方式写出其素因子的乘 ...
- poj 1845 【数论:逆元,二分(乘法),拓展欧几里得,费马小定理】
POJ 1845 题意不说了,网上一大堆.此题做了一天,必须要整理一下了. 刚开始用费马小定理做,WA.(poj敢说我代码WA???)(以下代码其实都不严谨,按照数据要求A是可以等于0的,那么结果自然 ...
- POJ1845 Sumdiv [数论,逆元]
题目传送门 Sumdiv Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 26041 Accepted: 6430 Des ...
- POJ 1845 Sumdiv 【二分 || 逆元】
任意门:http://poj.org/problem?id=1845. Sumdiv Time Limit: 1000MS Memory Limit: 30000K Total Submissions ...
- poj 1845 Sumdiv (等比求和+逆元)
题目链接:http://poj.org/problem?id=1845 题目大意:给出两个自然数a,b,求a^b的所有自然数因子的和模上9901 (0 <= a,b <= 50000000 ...
- POJ 1845 Sumdiv 【逆元】
题意:求A^B的所有因子之和 很容易知道,先把分解得到,那么得到,那么 的所有因子和的表达式如下 第一种做法是分治求等比数列的和 用递归二分求等比数列1+pi+pi^2+pi^3+...+pi^n: ...
随机推荐
- Confluence 6 数据中心的缓存
在 Confluence 数据中心(集群)你需要分布缓存和每一个节点的缓存.在集群管理界面,将会定义分布缓存和节点本地缓存. 缓存配置文件存储在集群共享目录中的 home 目录下面. https:// ...
- 如何使用PowerShell批量删除Office 365的用户
概述 本文将演示如何在必要的时候(例如在测试环境),通过PowerShell脚本批量删除Office 365的用户,首先需要通过Get-MsolUser的命令(并且配合筛选条件)获取到符合条件的用户列 ...
- Python匿名函数(lambda)
result = lambda [arg1 [, arg2, .....]]:expression result:用于调用lambda表达式 [arg1 [, arg2, -]]:可选参数,用于传递参 ...
- AI学习吧-购物车-添加商品接口
create接口流程 需求:向购物车添加商品 流程:写shopping_cart路由--->写ShoppingCart视图函数--->使用Authuser校验用户是否登录--->首先 ...
- Django目录结构分析
Django目录结构分析: Django的Linux项目目录记录 [root@cmdb Django]# tree mysite mysite ├── cmdb │ ├── admin.py # ...
- 安装和配置bazel
2018-12-26 21:56:23 编译和移植tensorflow的C/C++源码时,用到bazel这一构建工具.本篇blog记录遇到的安装.配置问题. 吐槽 构建工具,从make/ant/cma ...
- 字符转ASCII码
char k = '成'; int str = (int)k; Console.WriteLine(str); 结果25104就是‘成’对应的ASCII值
- CentOS 6.9 NFS安装和配置
1.安装依赖包 yum install nfs-utils rpcbind -y 2.开机启动 chkconfig rpcbind on chkconfig nfs on 3.创建一个共享目录和加权限 ...
- CentOS升级glibc-2.14
升级glibc-2.14用到的rpm https://pan.baidu.com/s/1v-Uk579TGM6498cExst6ow 先要安装gcc yum -y install gcc 执行: rp ...
- MVC异常处理(异常捕获)
1.cshtml页面异常 2.Controller异常 3.路由参数异常. 4.页面不存在404 页面不存在404,可以通过配置config来处理 <customErrors mode=&quo ...