题目大意就是给定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. 转:UML类图几种关系的总结

    转自:http://www.open-open.com/lib/view/open1328059700311.html 在UML类图中,常见的有以下几种关系: 泛化(Generalization),  ...

  2. MyBatis学习笔记(四) 注解

        使用MyBatis注解开发,可以省去类配置文件,简洁方便.但是比较复杂的SQL和动态SQL还是建议书写类配置文件. 注解还是不推荐使用的.只是了解了解!简单的CRUD可以使用注解.简单写写. ...

  3. Intent 隐式跳转,向下一个活动传递数据,向上一个活动返回数据。

    一.每个Intent只能指定一个action,多个Category. 使用隐式跳转,我们不仅可以跳转到自己程序内的活动,还可以启动其他程序的活动.使得Android多个程序之间的功能共享成为可能. 例 ...

  4. 利用ITextSharp导出PDF文件

    最近项目中需要到处PDF文件,最后上网搜索了一下,发现ITextSharp比较好用,所以做了一个例子: public string ExportPDF() { //ITextSharp Usage / ...

  5. chrome web开发工具

    顾名思义Chrome开发工具就是一个工具,它允许Web开发人员可以通过浏览器应用程序干预和操作Web页面,也可以通过这个工具调试和测试Web页面或Web应用程序.有了这个工具,你可以做很多有趣的事情: ...

  6. 通过yum安装nginx-mysql-php-fastcgi配置LNMP

    最近指想服务器跑静态文件,所以想单独配置个nginx的webserver,然而并不是我想象的那么简单,使用rpm包来安装会发生很多软件依赖的错误: 当我尝试使用yum安装nginx的时候,总是提示未找 ...

  7. SQL Server 2008 R2 开启允许远程连接

      方法/步骤 1 登陆SQL Server 2008(windows身份认证),登陆后右击,选择“属性”.   2 左侧选择“安全性”,选中右侧的“SQL Server 和 Windows 身份验证 ...

  8. 在XP下把win7安装到VHD,内存足够大可以RAMOS

    在XP下把win7安装到VHD,内存足够大可以RAMOS1.用DiskGenius创建VHD固定大小磁盘文件,以win7vhd.vhd为例,然后进行分区格式化,格式化时启用NTFS压缩.2.进入WIN ...

  9. Jsp-Servlet 那一大堆事儿--1

    为毛全局变量声明时初始化在try内不能用? import javax.servlet.http .*; import java.io.*; import javax.servlet.*; import ...

  10. iOS应用架构谈 组件化方案

    转载: iOS应用架构谈 组件化方案 简述 前几天的一个晚上在infoQ的微信群里,来自蘑菇街的Limboy做了一个分享,讲了蘑菇街的组件化之路.我不认为这条组件化之路蘑菇街走对了.分享后我私聊了Li ...