POJ 1845 Sumdiv 【二分 || 逆元】
任意门:http://poj.org/problem?id=1845、
Sumdiv
Time Limit: 1000MS |
Memory Limit: 30000K |
|
Total Submissions: 30268 |
Accepted: 7447 |
Description
Input
Output
Sample Input
2 3
Sample Output
15
Hint
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 【二分 || 逆元】的更多相关文章
- POJ 1845 Sumdiv 【逆元】
题意:求A^B的所有因子之和 很容易知道,先把分解得到,那么得到,那么 的所有因子和的表达式如下 第一种做法是分治求等比数列的和 用递归二分求等比数列1+pi+pi^2+pi^3+...+pi^n: ...
- POJ 1845 Sumdiv(逆元)
题目链接:Sumdiv 题意:给定两个自然数A,B,定义S为A^B所有的自然因子的和,求出S mod 9901的值. 题解:了解下以下知识点 1.整数的唯一分解定理 任意正整数都有且只有唯一的方式 ...
- poj 1845 POJ 1845 Sumdiv 数学模板
筛选法+求一个整数的分解+快速模幂运算+递归求计算1+p+p^2+````+p^nPOJ 1845 Sumdiv求A^B的所有约数之和%9901 */#include<stdio.h>#i ...
- POJ 1845 Sumdiv#质因数分解+二分
题目链接:http://poj.org/problem?id=1845 关于质因数分解,模板见:http://www.cnblogs.com/atmacmer/p/5285810.html 二分法思想 ...
- poj 1845 Sumdiv (等比求和+逆元)
题目链接:http://poj.org/problem?id=1845 题目大意:给出两个自然数a,b,求a^b的所有自然数因子的和模上9901 (0 <= a,b <= 50000000 ...
- POJ 1845 Sumdiv(因子分解+快速幂+二分求和)
题意:给你A,B,让求A^B所有的因子和模上9901 思路:A可以拆成素因子的乘积: A = p1^x1 * p2^x2 *...* pn^xn 那么A^B = p1^(B*x1) * p2^(B*x ...
- POJ 1845 Sumdiv [素数分解 快速幂取模 二分求和等比数列]
传送门:http://poj.org/problem?id=1845 大致题意: 求A^B的所有约数(即因子)之和,并对其取模 9901再输出. 解题基础: 1) 整数的唯一分解定理: 任意正整数都有 ...
- POJ 1845 Sumdiv(求因数和 + 逆元)题解
题意:给你a,b,要求给出a^b的因子和取模9901的结果. 思路:求因子和的方法:任意A = p1^a1 * p2^a2 ....pn^an,则因子和为sum =(1 + p1 + p1^2 + . ...
- poj 1845 Sumdiv(约数和,乘法逆元)
题目: 求AB的正约数之和. 输入: A,B(0<=A,B<=5*107) 输出: 一个整数,AB的正约数之和 mod 9901. 思路: 根据正整数唯一分解定理,若一个正整数表示为:A= ...
随机推荐
- sql语句将数字转为汉字展示
select [表字段Name] , ( case [表字段OrderState] when 1 then '已核销' when 2 then '确认前的移动端取消'when 3 then '已完成' ...
- 从代码层读懂 Java HashMap 的实现原理
概述 Hashmap继承于AbstractMap,实现了Map.Cloneable.Java.io.Serializable接口.它的key.value都可以为null,映射不是有序的.Hashmap ...
- 生成自签名证书-开启https
1.生成CA证书 # 生成 CA 私钥 openssl genrsa -out ca.key 2048 # X.509 Certificate Signing Request (CSR) Manage ...
- Hibernate 学习(二)
一.Hibernate 核心 API 1.Configuration 对象(配置) 配置对象是你在任何 Hibernate 应用程序中创造的第一个 Hibernate 对象,并且经常只在应用程序初始化 ...
- ApplicationHost.config文件被破坏导致IIS崩溃
“”Application Host Helper Service 在尝试删除历史目录“C:\inetpub\history\CFGHISTORY_0000000475”时遇到错误.将跳过并忽略此目录 ...
- csharp: Request.Form,Request.QueryString,Request.Params,Request.Cookies
/// <summary> /// Request.Form,Request.QueryString,Request.Params /// http://msdn.microsoft.co ...
- 比较全的css重设
一.最简化的CSS Reset(重设) : * { padding:; margin:; } 这是最普遍最简单的CSS重设,将所有元素的padding和margin值都设为0,可以避免一些浏览器在理解 ...
- 云计算的三种模式:IaaS、PaaS和SaaS
云计算主要分为三种服务模式,而且这个三层的分法重要是从用户体验的角度出发的: 1. Software as a Service,软件即服务,简称SaaS,这层的作用是将应用作为服务提供给客户. 2. ...
- MySQL--主从数据库同步原理
主从数据库的复制原理:摘自MySQL官网 1. 异步 * 主在执行sql之后,记录二进制bin-log文件. * 同时从连接主服务器,并从主获取binlog,存于本地relay-log,并从上次记 ...
- Excellent JD
Job description About the role We are looking for a talented engineer who has excellent cloud skills ...