题目链接http://poj.org/problem?id=1845

题目大意:A^B的所有约数和,mod 9901.

解题思路

①整数唯一分解定理:

一个整数A一定能被分成:A=(P1^K1)*(P2^K2)*(P3^K3).....*(Pn^Kn)的形式。其中Pn为素数。

如2004=(22)*3*167。

那么2004x=(22x)*(3x)*(167x)。

②约数和公式

对于一个已经被分解的整数A=(P1^K1)*(P2^K2)*(P3^K3).....*(Pn^Kn),

有约数和S=(1+P12+P13+.....P1k1)*.....(1+Pn2+Pn3+.....Pnkn)。

(1+P12+P13+.....P1k1)是一个等比数列,化简为(P1k1+1 -1)/(P1-1),由于有除法同余式,很容易想到乘法逆元。

但是这题和HDU 1452不同,对于逆元表达式ax=1 mod n,乘法逆元存在的条件是gcd(a,n)=1,即a,n互质,但是这题的gcd(P1-1,9901)≠1, 所以不能用乘法逆元求解。

所以有必要对等比数列求和公式改一改:

(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))

上式红色加粗的前半部分恰好就是原式的一半,后半部分递归求解即可。

(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);

这样,在对A质因数分解后,对于每一个质因数,累乘sum(质因数,次数)%mod即可,注意sum计算的时候都要mod防止溢出。

注意一下A的范围,A=0或A=1时无法分解质因数,所以特判结果分别是0和1。

#include "cstdio"
#include "map"
using namespace std;
#define LL long long
#define mod 9901
map<LL,LL> prime_factor(LL n)
{
map<LL,LL> res;
for(LL i=;i*i<=n;i++)
while(n%i==) {++res[i];n/=i;}
if(n!=) res[n]=;
return res;
}
LL pow(LL a,LL n)
{
LL base=a,ret=;
while(n)
{
if(n&) ret=(ret*base)%mod;
base=(base*base)%mod;
n>>=;
}
return ret%mod;
}
LL sum(LL p,LL n)
{
if(n==) return ;
if(n&) return ((+pow(p,(n>>)+))*sum(p,n>>))%mod;
else return ((+pow(p,(n>>)+))*sum(p,(n-)>>)+pow(p,n>>))%mod;
}
int main()
{
//freopen("in.txt","r",stdin);
LL a,b,res=;
scanf("%I64d%I64d",&a,&b);
if(a==) {printf("0\n");return ;}
map<LL,LL> fac=prime_factor(a);
for(map<LL,LL>::iterator i=fac.begin();i!=fac.end();i++)
{
LL tmp=sum(i->first,i->second*b)%mod;
res=(tmp*res)%mod;
}
printf("%I64d\n",res);
}
13625416 neopenx 1845 Accepted 148K 0MS C++ 992B 2014-11-13 12:53:25

POJ 1845 (约数和+二分等比数列求和)的更多相关文章

  1. POJ 1845 Sumdiv 【二分 || 逆元】

    任意门:http://poj.org/problem?id=1845. Sumdiv Time Limit: 1000MS Memory Limit: 30000K Total Submissions ...

  2. 【POJ1845】Sumdiv(数论/约数和定理/等比数列二分求和)

    题目: POJ1845 分析: 首先用线性筛把\(A\)分解质因数,得到: \[A=p_1^{a_1}*p_2^{a_2}...*p_n^{a_n} (p_i是质数且a_i>0) \] 则显然\ ...

  3. poj 3233 Matrix Power Series 矩阵求和

    http://poj.org/problem?id=3233 题解 矩阵快速幂+二分等比数列求和 AC代码 #include <stdio.h> #include <math.h&g ...

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

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

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

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

  6. poj 1845 数论综合

    题意:求A^B的所有因数的和 mod 9901 sol:一开始毫无思路,因为很多定理都不知道-_-|| 1. 整数的唯一分解定理: 任意正整数都有且只有一种方式写出其素因子的乘积表达式. A=(p1^ ...

  7. POJ 1845 Sumdiv 【逆元】

    题意:求A^B的所有因子之和 很容易知道,先把分解得到,那么得到,那么 的所有因子和的表达式如下 第一种做法是分治求等比数列的和  用递归二分求等比数列1+pi+pi^2+pi^3+...+pi^n: ...

  8. POJ 1845 Sumdiv (求某个数的所有正因子的和)

    题意: 求A^B的所有正因子的和,最后模9901的结果. 思路: 若对一个数n进行素数分解,n=p1^a1*p2^a2*p3^a3*...*pk^ak那么n的所有正因子之和sum=(1+p1+...+ ...

  9. poj 1845 POJ 1845 Sumdiv 数学模板

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

随机推荐

  1. 判断图片的类型(图片是data类型 )

    + (NSString *)typeForImageData:(NSData *)data { uint8_t c; [data getBytes:&c length:1]; switch ( ...

  2. Java集合源码学习(三)LinkedList分析

    前面学习了ArrayList的源码,数组是顺序存储结构,存储区间是连续的,占用内存严重,故空间复杂度很大.但数组的二分查找时间复杂度小,为O(1),数组的特点是寻址容易,插入和删除困难.今天学习另外的 ...

  3. HTTPS的一些疑问解答

    PHP写的网站怎么用https访问,具体要怎样 这跟用什么语言写的网站没有关系,可以去申请个快速的SSL证书,一年也就几十块. 开启apache server的ssl,自己做个免费的ssl证书或者去申 ...

  4. 情定XMLA,割舍不下的XAML

    俗话说,不玩Silverlight的APP Developer,在DBA圈里就不是好的数据分析师.嗯,你没看错,题目里,一样东西是XMLA,一样东西是XAML.前者是用来玩SSAS的 ,一样是用来玩S ...

  5. Spring+Hibernate+Oracle中的Clob操作配置

    bean对象配置: <!-- 此处用于指定当前JDBC的实现,详见下面注解① --> <bean id="nativeJdbcExtractor" class=& ...

  6. 无法启动程序 ”*.lib”

    解决办法: 把含有入口函数(main函数)的 工程 如 cpp-test 设置为启动项 具体操作: 选中 cpp-test 工程 右击 —> 设为启动项目

  7. apk签名(不打包)

    apk提交给应用市场加固后,需要重新签名 签名工具:360签名 下载地址:http://yunpan.cn/cm8GqVWL7Y8Eh 签名步骤:http://jiagu.360.cn/qcms/he ...

  8. Sql数据库帮组类

    这段时间闲下来写了一些东西,重新写了一个简单的数据库帮组类 public class MyDBHelper { public static readonly string connString = C ...

  9. C语言补码作用

    补码主要是为了cpu运算器在进行减法运算时避免借位而设立的. 在早期,cpu中的运算器部分,只要实现一个加法器就可以完成四由算术运算. 因为计算机中的数值编码是有限位数的,所以减法实际上相当于加上减数 ...

  10. windows下cmd操作

    进入文件夹:cd 文件夹名 列出文件列表:dir 清屏:cls