任意门: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. (转载).NET的五层架构

    我们刚开始学习架构的时候,首先会想到分层的概念,分层架构比较经典的是三层架构,那么,什么是三层架构呢?它包括表现层,业务层,数据访问层:而对于一个新手来说,从抽象意义上的三层架构,逻辑上就划分为三个层 ...

  2. 使用union合并查询

    语法: select …..from 表1 union select ……from 表2 2. 合并查询的特点 ① 合并的表中的列的个数.数据类型必须相同或向兼容. ② union默认去掉重复值,如果 ...

  3. HTML <a>标签的使用

    <a></a>标签称作链接标记,由<a>与</a>所围的文字.图片等可以作为一个链接 Eg:<a href="index.html&qu ...

  4. easyui内嵌iframe问题解决

    项目中使用easyui的tab页,每个tab页均内嵌iframe,现在要在tab页中控制新增一个同级别的tab页,记录如下: 首先是main.html主页面: <div class=" ...

  5. Java实现内存分配算法 FF(首次适应算法) BF(最佳适应算法)

    一.概述 因为这次os作业对用户在控制台的输入输出有要求,所以我花了挺多的代码来完善控制台的显示. MemoryAlgorithm类里只是和控制台输入输出有关的操作,而对内存的所有逻辑操作都是用Mem ...

  6. SQL SEVERE 基本用法 1

    知识点: 数据库的存储结构分为逻辑存储结构和物理存储结构两种, 其中逻辑存储结构指是由那些信息组成,物理存储结构是指如何在磁盘上存储数据库文件的. 数据库文件由数据文件和事务日志文件组成,一个数据库至 ...

  7. Windows安装配置xampp

    建议大家直接看原文 1.安装XAMPP 进入https://www.apachefriends.org/zh_cn/index.html页面下载XAMPP 2 3.打开xampp控制版 4.修改apa ...

  8. MySQL root 密码修改

    小伙伴要在以前的服务器上装个代码版本控制的软件,要用到数据库,可是想来找去root密码还是忘了,其他已经安装的服务都是用的专用账户配置文件里要找不到root用户的密码.用以下方法将密码强制修改掉: 1 ...

  9. SPOJ:COT2 Count on a tree II

    题意 给定一个n个节点的树,每个节点表示一个整数,问u到v的路径上有多少个不同的整数. n=40000,m=100000 Sol 树上莫队模板题 # include <bits/stdc++.h ...

  10. js-滚动到指定位置导航栏固定顶部

    最近整理一下之前做的一个项目,把滚动条动态固定顶部的代码整理出来和大家分享,上代码 <!DOCTYPE html> <html> <head> <meta c ...