关闭

POJ 1845-Sumdiv 数论 +快速幂&&筛素&&分解质因数&&求因数之和的模板

405人阅读 评论(0) 收藏 举报
分类:

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;
}
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:46380次
    • 积分:2408
    • 等级:
    • 排名:第16120名
    • 原创:203篇
    • 转载:0篇
    • 译文:0篇
    • 评论:7条
    最新评论