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 题解(数论,约数和公式,逆元,高中数学)

POJ1845 Sumdiv(求所有因数和+矩阵快速幂)

POJ1845 Sumdiv - 乘法逆元+快速幂A^B的约数个数和

2018.11.6刷题记录

题解POJ1845 Sumdiv(乘法逆元+约数和)

POJ 1845 Sumdiv (整数拆分+等比快速求和)