POJ 1845-Sumdiv 数论 +快速幂&&筛素&&分解质因数&&求因数之和的模板
Posted acblacktea
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 1845-Sumdiv 数论 +快速幂&&筛素&&分解质因数&&求因数之和的模板相关的知识,希望对你有一定的参考价值。
poj计划的第一个坎,非常经典的一道题在此记录一下以后总结
知识点:
1 (a+b)%c = (a%c+b%c)%c
(a*b)%c = ((a%c)*(b%c))%c
2 计算a^n 要用快速幂((logn)渣渣我都能迅速打出来)
3 任何数都能分解成几个质因数相乘
4 求一个数的所有因数之和 = (a^0+a^1+a^2+a^3+….a^n) * ( a1^0+a1^1+a1^2+a1^3+….a1^n1)* (a2^0+a2^1+a2^2+a2^3+….a2^n2)…..*(an^0+an^1+an^2+an^3+….an^nn)
其中a,a1,a2,,,,代表它的质因数,n,n1,n2….nn代表它所代表的质因数的个数
5 二分求a^0+a^1+a^2……a^n的结果,二分很抽象新手难以想到现屡一下思路。。。
(1) 先分析n为奇数时a^n/a^(n/2)=a^(n/2+1)/a^0=a^(n/2+2)/a^1=…=a^(n/2+1);
所以 a^0+a^1+a^2……a^n = a^0+a^1+a^2+….a^n/2+a^(n/2+1)( a^0+a^1+a^2+….a^n/2) = (1+a^(n/2+1) (a^0+a^1+a^2+….a^n/2 )
(2)当分析n为偶数时同分析奇数一样都有对应关系,下标0跟n/2+1,1跟n/2+2……n/2-1跟n所代表的a值相除都可以得同一个系数为a^(n/2+1)。但有一组不一样就是a^n/2;
没有系数与它对应所以要另算
所以递推公式为a^0+a^1+a^2……a^n = a^0+a^1+a^2+….a^n/2+a^(n/2+1)( a^0+a^1+a^2+….a^(n/2-1)) = (1+a^(n/2+1) (a^0+a^1+a^2+….a^(n/2-1 ))+a^(n/2);
6 细心该取模的地方别忘写了一下写对不然以后查错很麻烦,同时这种数论题数据很作你是不能想出特殊数据的,要中途wa只能眼睛干瞪差错(写给马虎的渣渣自己)
PS: 我也看题解写的。。。但题解都写得很简单,一股装逼的味道。。。我自己还是要屡一下证明的细节要不就是全抄的了。。另外把这个当以后的模板了很有用的。
//2015.11.20 by blacktea
//筛素数&&分解质因子&&快速幂&&二分求所有因子的和->模板
#include<cstdio>
#include<cstring>
#define mod 9901
int am[10000],x,n,l=0,pri[10000],prix[2000],l1;
__int64 priam[2000];
void toGetPrime()//筛素数
for(int i=2;i<=10000;i++)
if(!am[i])
pri[l] = i;
l++;
for(int j=2;j*i<=10000;j++)
am[i*j] = 1;
void toApartPrime()//分解质因子
memset(priam,0,sizeof(priam));
l1=0;
for(int i=0;pri[i]*pri[i]<=x;i++)
if(!(x%pri[i]))
prix[l1] = pri[i];
while(x%pri[i]==0)
x/=pri[i];
priam[l1]++;
priam[l1]*=n;
l1++;
if(x!=1)prix[l1] = x;priam[l1] = 1;priam[l1]*=n;l1++;
int pow_m(int a,__int64 n)//快速幂
a%=mod;
int result = 1,pre = a;
while(n)
if(n&1)
result *= pre;result %= mod;
pre*=pre;
pre%=mod;
n>>=1;
return result;
int toCalculate(int a,__int64 sum)//二分求所有因子的和
int result = 1;
if(sum==0)return 1;
if(sum%2)result = ((1+pow_m(a,sum/2+1))%mod)*toCalculate(a,sum/2);
else result = ((1+pow_m(a,sum/2+1))%mod)*toCalculate(a,sum/2-1)+pow_m(a,sum/2);
result%=mod;
return result;
int main()
toGetPrime();
while(scanf("%d%d",&x,&n)!=EOF)
int result =1;
if(x==1)printf("1\\n");continue;
else if(x==0)printf("0\\n");continue;
toApartPrime();
for(int i=0;i<l1;i++)
result*=toCalculate(prix[i],priam[i]);
result%=mod;
printf("%d\\n",result);
return 0;
以上是关于POJ 1845-Sumdiv 数论 +快速幂&&筛素&&分解质因数&&求因数之和的模板的主要内容,如果未能解决你的问题,请参考以下文章
POJ 1845-Sumdiv 题解(数论,约数和公式,逆元,高中数学)