任意门:http://poj.org/problem?id=1845

Sumdiv

Time Limit: 1000MS

Memory Limit: 30000K

Total Submissions: 30268

Accepted: 7447

Description

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.

Output

The 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). 

Source

题目概括:

给出 A 和 B ,求 AB 所有因子之和,答案 mod 9901;

解题思路:

可对 A 先进行素因子分解 A = p1a1 * p2a2 * p3a3 * ...... * pnan

即 AB = p1a1*B * p2a2*B * p3a3*B * ...... * pnan*B

那么 AB 所有因子之和 = (1 + P11 + P12 + P13 + ... + P1a1*B) *  (1 + P21 + P22 + P23 + ... + P2a2*B) * ......* (1 + Pn1 + Pn2 + Pn3 + ... + Pnan*B) ;

对于  (1 + P1 + P2 + P3 + ... + Pa1*B) 我们可以

①二分求和 (47 ms)

AC code:

 #include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const LL MOD = ;
const int MAXN = 1e4+;
LL p[MAXN];
bool isprime[MAXN];
int cnt;
LL A, B; void init() //打表预处理素因子
{
cnt = ;
memset(isprime, , sizeof(isprime));
for(LL i = ; i < MAXN; i++){
if(isprime[i]){
p[cnt++] = i;
for(int j = ; j < cnt && p[j]*i < MAXN; j++)
isprime[p[j]*i] = false;
}
}
} LL qpow(LL x, LL n)
{
LL res = 1LL;
while(n){
if(n&) res = (res%MOD*x%MOD)%MOD;
x = (x%MOD*x%MOD)%MOD;
n>>=1LL;
}
return res;
} LL sum(LL x, LL n)
{
if(n == ) return ;
LL res = sum(x, (n-)/);
if(n&){
res = (res + res%MOD*qpow(x, (n+)/)%MOD)%MOD;
}
else{
res = (res + res%MOD*qpow(x, (n+)/)%MOD)%MOD;
res = (res + qpow(x, n))%MOD;
}
return res;
} int main()
{
LL ans = ;
scanf("%lld %lld", &A, &B);
init();
//printf("%d\n", cnt);
for(LL i = ; p[i]*p[i] <= A && i < cnt; i++){ //素因子分解
//printf("%lld\n ", p[i]);
if(A%p[i] == ){
LL num = ;
while(A%p[i] == ){
num++;
A/=p[i];
}
ans = ((ans%MOD*sum(p[i], num*B)%MOD)+MOD)%MOD;
}
}
if(A > ){
// puts("zjy");
ans = (ans%MOD*sum(A, B)%MOD+MOD)%MOD;
} printf("%lld\n", ans); return ;
}

②应用等比数列求和公式 ( 0ms )

因为要保证求模时的精度,所以要求逆元。

这里用的方法是一般情况都适用的 : A/B mod p = A mod (p*B) / B;

但是考虑乘法会爆int,所以自定义一个二分乘法。

AC code:

 // 逆元 + 二分乘法
#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int MAXN = 1e4+;
const LL mod = ;
int p[MAXN], cnt;
bool isp[MAXN];
LL A, B; void prime()
{
memset(isp, , sizeof(isp));
isp[] = isp[] = false;
for(int i = ; i < MAXN; i++){
if(isp[i]){
p[cnt++] = i;
for(int k = ; k < cnt && i*p[k] < MAXN; k++){
isp[i*p[k]] = false;
}
}
}
} LL mutil(LL x, LL y, LL MOD)
{
LL res = ;
while(y){
if(y&) res = (res+x)%MOD;
x = (x+x)%MOD;
y>>=1LL;
}
return res;
} LL q_pow(LL x, LL n, LL MOD)
{
LL res = 1LL;
while(n){
if(n&) res = mutil(res, x, MOD)%MOD;
x = mutil(x, x, MOD)%MOD;
n>>=1LL;
}
return res;
} int main()
{
LL num = ;
LL ans = ;
scanf("%lld %lld", &A, &B);
prime();
for(int i = ; p[i]*p[i] <= A; i++){
if(A%p[i] == ){
num = ;
while(A%p[i] == ){
A/=p[i];
num++;
}
LL m = mod*(p[i]-);
ans *= (q_pow(p[i], num*B+, m) + m-)/(p[i] - );
ans = ans%mod;
//ans += ((q_pow(p[i], num*B, mod*(p[i]-1))-p[i])/(p[i]-1))%mod;
}
} if(A != ){
// ans += ((q_pow(A, B, mod*(A-1))-A)/(A-1))%mod;
LL m = mod*(A-);
ans*=(q_pow(A, B+, m)+m-)/(A-);
ans = ans%mod;
} printf("%lld\n", ans); return ;
}

POJ 1845 Sumdiv 【二分 || 逆元】的更多相关文章

  1. POJ 1845 Sumdiv 【逆元】

    题意:求A^B的所有因子之和 很容易知道,先把分解得到,那么得到,那么 的所有因子和的表达式如下 第一种做法是分治求等比数列的和  用递归二分求等比数列1+pi+pi^2+pi^3+...+pi^n: ...

  2. POJ 1845 Sumdiv(逆元)

    题目链接:Sumdiv 题意:给定两个自然数A,B,定义S为A^B所有的自然因子的和,求出S mod 9901的值. 题解:了解下以下知识点   1.整数的唯一分解定理 任意正整数都有且只有唯一的方式 ...

  3. poj 1845 POJ 1845 Sumdiv 数学模板

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

  4. POJ 1845 Sumdiv#质因数分解+二分

    题目链接:http://poj.org/problem?id=1845 关于质因数分解,模板见:http://www.cnblogs.com/atmacmer/p/5285810.html 二分法思想 ...

  5. poj 1845 Sumdiv (等比求和+逆元)

    题目链接:http://poj.org/problem?id=1845 题目大意:给出两个自然数a,b,求a^b的所有自然数因子的和模上9901 (0 <= a,b <= 50000000 ...

  6. POJ 1845 Sumdiv(因子分解+快速幂+二分求和)

    题意:给你A,B,让求A^B所有的因子和模上9901 思路:A可以拆成素因子的乘积: A = p1^x1 * p2^x2 *...* pn^xn 那么A^B = p1^(B*x1) * p2^(B*x ...

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

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

  8. POJ 1845 Sumdiv(求因数和 + 逆元)题解

    题意:给你a,b,要求给出a^b的因子和取模9901的结果. 思路:求因子和的方法:任意A = p1^a1 * p2^a2 ....pn^an,则因子和为sum =(1 + p1 + p1^2 + . ...

  9. poj 1845 Sumdiv(约数和,乘法逆元)

    题目: 求AB的正约数之和. 输入: A,B(0<=A,B<=5*107) 输出: 一个整数,AB的正约数之和 mod 9901. 思路: 根据正整数唯一分解定理,若一个正整数表示为:A= ...

随机推荐

  1. javascript进行base64加密,解密

    function Base64() { // private property _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr ...

  2. C# 多线程系列之Semaphore使用

    Semaphore,即信号量的意思.是操作系统原始提供的内核同步对象. Semaphore semaphoreAcceptedClients = , 3,"Semaphore1") ...

  3. Emmet使用方法

    本文摘自:http://www.iteye.com/news/27580 Emmet的前身是大名鼎鼎的Zen coding,如果你从事Web前端开发的话,对该插件一定不会陌生.它使用仿CSS选择器的语 ...

  4. ThreadLocal介绍以及源码分析

    ThreadLocal 线程主变量 前面部分引用其他优秀博客,后面源码自己分析的,如有冒犯请私聊我. 用Java语言开发的同学对 ThreadLocal 应该都不会陌生,这个类的使用场景很多,特别是在 ...

  5. 【转载】从创业者角度看《印度合伙人 Padman》后的一点感受

    ***************************** 这部电影看简介是真实事件改编的,当时除了电影本身的精彩和主角宠妻狂魔之外,印象最深的就是感觉到主角的创业者心态是一步步在生活中被培养的.特别 ...

  6. HADOOP背景介绍

    1. HADOOP背景介绍 1.1 什么是HADOOP 1. HADOOP是apache旗下的一套开源软件平台 2. HADOOP提供的功能:利用服务器集群,根据用户的自定义业务逻辑,对海量数据进行分 ...

  7. iSCSI配置

    iSCSI介绍 几种存储的架构: 直接存取 (direct-attached storage):例如本机上面的磁盘,就是直接存取设备: 透过储存局域网络 (SAN):来自网络内的其他储存设备提供的磁盘 ...

  8. 07_zookeeper的客户端工具curator_基本api

    [zk原生api的不足之处] * 不能自动超时重连,需要手动操作 * watcher事件注册一次后就会失效 * 不支持递归创建节点 [ Apache curator ] * 解决了watcher的注册 ...

  9. SQL Server ->> SQL Server 2016重要功能改进之 -- INSERT SELECT时并发插入数据

    SQL Server 2016对INSERT INTO XXXX SELECT语句进行了优化,在某些情况下可以触发数据的并行插入,但是要求兼容模式是130(SQL Server 2016)以及在插入的 ...

  10. SQL Server 2016 ->> T-SQL新特性

    1) TRUNCATE表分区而不是整表 CREATE TABLE dbo.TruncatePartitionTest ( PrtCol INT, Col2 ) ) ON [myPS1](PrtCol) ...