题目大意就是给定a和b,求a^b的约数和

f(n) = sigma(d) [d|n]

这个学过莫比乌斯反演之后很容易看出这是一个积性函数

那么f(a*b) = f(a)*f(b)  (gcd(a,b)=1)

那么这道题就可以将a分解为每一个素数的k次方,求出相对应的f(p^k),将每一个乘在一起就行了

因为每一个素数得到的都是只有唯一的素数因子,那么f(n) 又变成了求 a^0+a^1+a^2....+a^k的值了 (n=a^k)

这里因为要取模,所以我用的是矩阵快速幂求的,网上别人用的都是二分分治求等比数列,反正这两种方法都不需要逆元,都能过

但我最开始写的要逆元的方法过不了也不知道为什么,希望路过大神知道的提个醒

矩阵快速幂的矩阵构造两维,第一维是等比关系,第二维保存前面所有值的和

{

a , a

0 , 1

}

分治求等比数列的和:

3: 用递归二分求等比数列1+pi+pi^2+pi^3+...+pi^n:

(1)若n为奇数,一共有偶数项,则:
      1 + p + p^2 + p^3 +...+ p^n

= (1+p^(n/2+1)) + p * (1+p^(n/2+1)) +...+ p^(n/2) * (1+p^(n/2+1))
      = (1 + p + p^2 +...+ p^(n/2)) * (1 + p^(n/2+1))

上式红色加粗的前半部分恰好就是原式的一半,那么只需要不断递归二分求和就可以了,后半部分为幂次式,将在下面第4点讲述计算方法。

(2)若n为偶数,一共有奇数项,则:
      1 + p + p^2 + p^3 +...+ p^n

= (1+p^(n/2+1)) + p * (1+p^(n/2+1)) +...+ p^(n/2-1) * (1+p^(n/2+1)) + p^(n/2)
      = (1 + p + p^2 +...+ p^(n/2-1)) * (1+p^(n/2+1)) + p^(n/2);

上式红色加粗的前半部分恰好就是原式的一半,依然递归求解

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
#define ll long long
const int MOD = ; struct Matrix{
int m[][];
void init(){memset(m , , sizeof(m)); m[][] = m[][] = ;}
Matrix operator*(const Matrix &p)const {
Matrix ans ;
for(int i= ; i< ; i++)
for(int j= ; j< ; j++){
ans.m[i][j] = ;
for(int k= ; k< ; k++)
ans.m[i][j] = (ans.m[i][j]+m[i][k]*p.m[k][j]%MOD)%MOD;
}
return ans;
}
void out(){
cout<<m[][]<<" "<<m[][]<<endl<<m[][]<<" "<<m[][]<<endl;
}
}; Matrix q_pow(Matrix a , int b)
{
Matrix ans;
ans.init();
while(b){
if(b&) ans = ans*a;
a = a*a ; b>>=;
}
return ans;
} int get(int a , int b)
{
//a^0+a^1+a^2...+a^b
Matrix p;
p.m[][] = a%MOD , p.m[][] = a%MOD , p.m[][] = , p.m[][] = ;
p = q_pow(p , b);
return (p.m[][]+p.m[][])%MOD;
} void fenjie(int a , int b)
{
int mx = (int)sqrt(a+0.5) , ret = ;
for(int i= ; i<=mx ; i++){
if(i>a) break;
int cnt = ;
while(a%i==){
cnt+=b , a/=i;
}
if(cnt) ret = (ret*get(i , cnt))%MOD;
}
if(a>) ret = (ret*get(a , b))%MOD;
printf("%d\n" , ret);
} int main() {
// freopen("a.in" , "r" , stdin);
// freopen("compare.txt" , "w" , stdout);
int a , b;
while(~scanf("%d%d" , &a , &b)){
if(a == ) puts("");
else fenjie(a , b);
}
return ;
}

矩阵快速幂

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
#define ll long long
const int MOD = ; int q_pow(int a , int b)
{
a = a%MOD;
int ret = ;
while(b){
if(b&) ret = ret*a%MOD;
a = a*a%MOD ; b>>=;
}
return ret;
} int inv(int a){return q_pow(a , MOD-);} int sum(int a , int b)
{
//a^0+a^1+a^2...+a^b
if(b==) return ;
if(a==) return ;
if(b&) return ((+q_pow(a , b/+))%MOD*(sum(a , b/)%MOD))%MOD;
else return ((+q_pow(a , b/+))%MOD*(sum(a , b/-)%MOD)%MOD+(q_pow(a , b/)%MOD))%MOD;
} void fenjie(int a , int b)
{
int mx = (int)sqrt(a+0.5) , ret = ;
for(int i= ; i<=mx ; i++){
if(i>a) break;
int cnt = ;
while(a%i==){
cnt+=b , a/=i;
}
if(cnt) ret = (ret*sum(i , cnt))%MOD;
}
if(a>) ret = (ret*sum(a , b))%MOD;
printf("%d\n" , ret);
} int main() {
// freopen("a.in" , "r" , stdin);
// freopen("compare.txt" , "w" , stdout);
int a , b;
while(~scanf("%d%d" , &a , &b)){
if(a == ) puts("");
else fenjie(a , b);
}
return ;
}

分治

POJ 1845 求a^b的约数和的更多相关文章

  1. 【POJ 1845】 Sumdiv (整数唯分+约数和公式+二分等比数列前n项和+同余)

    [POJ 1845] Sumdiv 用的东西挺全 最主要通过这个题学了约数和公式跟二分求等比数列前n项和 另一种小优化的整数拆分  整数的唯一分解定理: 随意正整数都有且仅仅有一种方式写出其素因子的乘 ...

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

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

  3. poj 1845 POJ 1845 Sumdiv 数学模板

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

  4. poj 1845 【数论:逆元,二分(乘法),拓展欧几里得,费马小定理】

    POJ 1845 题意不说了,网上一大堆.此题做了一天,必须要整理一下了. 刚开始用费马小定理做,WA.(poj敢说我代码WA???)(以下代码其实都不严谨,按照数据要求A是可以等于0的,那么结果自然 ...

  5. Java求555 555的约数中最大的三位数。

    package org.llh.test; /** * 求555 555的约数中最大的三位数 * @author llh * */ public class Car { //整数j除以整数i(i≠0) ...

  6. Sumdiv POJ - 1845 (逆元/分治)

    Consider two natural numbers A and B. Let S be the sum of all natural divisors of A^B. Determine S m ...

  7. POJ 1845 Sumdiv (整数唯一分解定理)

    题目链接 Sumdiv Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 25841   Accepted: 6382 Desc ...

  8. POJ - 1845 简单数论

    求A^B的约数和模MOD 对A质因子分解P1^k1*P2^k2....P^kn A^B既指数对应部分乘以B 对于每个P都有(1+P^1+P^2+...+P^ki)的选择 连乘每一个P的等比数列之和即可 ...

  9. 【简●解】POJ 1845 【Sumdiv】

    POJ 1845 [Sumdiv] [题目大意] 给定\(A\)和\(B\),求\(A^B\)的所有约数之和,对\(9901\)取模. (对于全部数据,\(0<= A <= B <= ...

随机推荐

  1. N-Queens II

    Description: Follow up for N-Queens problem. Now, instead outputting board configurations, return th ...

  2. Mac 实用工具与问题解决

    1.在dock上方的一长溜,被我拖成个方块了 删掉里面的字符,然后按esc 即可! 2.FIT输入法(Fun Input Toy),是苹果操作系统OS X上的免费中文输入法,支持全拼/双拼/全双混拼, ...

  3. MyBatis——调用存储过程

    原文:http://www.cnblogs.com/xdp-gacl/p/4270352.html 一.提出需求 查询得到男性或女性的数量, 如果传入的是0就女性否则是男性 二.准备数据库表和存储过程 ...

  4. 使用JSPatch平台热修复iosApp

    IOS产品开发中常常会遇到这种情况,线上发现一个严重bug,可能是一个crash,可能是一个功能无法使用,这时能做的只是赶紧修复Bug然后提交等待漫长的审核,即使申请加急也不会快到那里去,即使审核完了 ...

  5. Druid 数据库用户密码加密 代码实现

    druid-1.0.16.jar 阿里巴巴的开源数据连接池 jar包 明文密码+私钥(privateKey)加密=加密密码 加密密码+公钥(publicKey)解密=明文密码 程序代码如下: pack ...

  6. ios开发者证书 签发者无效

    2月14日以后,由于苹果更新安全证书:会导致本机制作的所有开发者证书无效: 钥匙串里的开发者证书无法使用 解决方式: 重新下载苹果公司的安全证书,并安装 1: 先在钥匙串里搜索到老的证书,如果有,请先 ...

  7. robotframework笔记20

    配置执行 选择测试用例 机器人框架提供了几个选择的命令行选项 执行测试用例. 也工作在相同的选项 后处理输出与 Rebot . 通过测试套件和测试用例的名称 测试套件和测试用例可以选择通过他们的名字的 ...

  8. 用过的正则(更新ing)

    http://www.debuggex.com/   这个很好用20120912 //十六进制颜色值的正则表达式 var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6} ...

  9. 《javascript高级程序设计》 第25章 新兴的API

    25.1 requestAnimationFrame() 25.1.1 早期动画循环 25.1.2 循环间隔的问题 25.1.3 mozRequestAnimation-Frame.webkitReq ...

  10. SO修改

    FUNCTION Z_SD_SALESORDER_CHANGE1. *"----------------------------------------------------------- ...