题目大意就是给定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. 【ufldl tutorial】Convolution and Pooling

    卷积的实现: 对于每幅图像,每个filter,首先从W中取出对应的filter: filter = squeeze(W(:,:,filterNum)); 接下来startercode里面将filter ...

  2. 转 java List 与ArrasyList 区别

    转 List是一个接口,而ListArray是一个类, ListArray继承并实现了List. 为什么要用 List list = new ArrayList() ,而不用 ArrayList al ...

  3. 通过NORFLASH中的uboot烧写uboot到nandFlash

    在mini2440的教程中,在构建nandflash系统的时候是首先通过supervivi借助dnw烧写uboot.bin到nand flash 第零块, 由于我使用的是64位操作系统,usb驱动没安 ...

  4. RecyleView

    RecyclerView是经典的ListView的进化与升华,它比ListView更加灵活,但也因此引入了一定的复杂性. 我们知道,ListView通过使用ViewHolder来提升性能.ViewHo ...

  5. 如何创建和使用XMLHttpRequest对象?

    创建XMLHttpRequest对象,我有以下几种方法,顺带给大家介绍下他们的使用,一起来看看那吧. 1. 第一种,我们可以使用构造函数的方式.直接new的方式,这样我们就构造了这个对象. reque ...

  6. Python开发者须知 —— Bottle框架常见的几个坑

    Bottle是一个小巧实用的python框架,整个框架只有一个几十K的文件,但却包含了路径映射.模板.简单的数据库访问等web框架组件,而且语法简单,部署方便,很受python开发者的青睐.Pytho ...

  7. easyui 上传文件代码

    using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.IO;usi ...

  8. 如何增加Asp.Net Core生成的模板网站中用户信息表中的列(AspNetUsers)

    环境: 1.VS2015 Community 14.0.25431.01 Update 3; 2.其他环境(具体哪一个影响不太清楚,都列在这儿) 使用的系统模板 利用系统提供的模板,并选择个人身份验证 ...

  9. ing

    #include <stdio.h> int main(){ int a,b; while(scanf("%d%d",&a,&b)!=EOF & ...

  10. 函数内部的函数中的this都是指向window

    刚看到一个问题关于this的, var name="the window"; var object={ name:"silence", packname:fun ...