Pentium.Labs

System全家桶:https://zhuanlan.zhihu.com/c_1238468913098731520

导航

poj 1845 数论综合

题意:求A^B的所有因数的和 mod 9901

 

sol:一开始毫无思路,因为很多定理都不知道-_-||

1. 整数的唯一分解定理:

任意正整数都有且只有一种方式写出其素因子的乘积表达式。

A=(p1^k1)*(p2^k2)*(p3^k3)*....*(pn^kn)   其中pi均为素数

2. 约数和公式:
对于已经分解的整数A=(p1^k1)*(p2^k2)*(p3^k3)*....*(pn^kn)
有A的所有因子之和为
S = (1+p1+p1^2+p1^3+...p1^k1) * (1+p2+p2^2+p2^3+….p2^k2) * (1+p3+ p3^3+…+ p3^k3) * .... * (1+pn+pn^2+pn^3+...pn^kn)

 

熟悉了公式定理就好办了。

首先求出p[i]、k[i]

然后就有

A=p1^n1*p2^n2*......*pk^nk

A^B=(p1^(B*n1))*(p2^(b*n2))*......*(pk^(b*nk))

然后求出S即可。

 注意:一开始我用等比数列求和公式求S,还用了pow_mod。其实这样不行。

比如数据59407 1,

59407 mod 9901=1,最终得出的结果成了0

模运算也不是随便用的,还得按公式来= =

 

Reference:http://blog.csdn.net/lyy289065406/article/details/6648539

 

 1 #include "iostream"
 2 #include "cstdio"
 3 using namespace std;
 4 #define P 9901
 5 #define LL __int64
 6 LL n[1000],p[1000];    //A=**(p[i]^n[i])
 7 LL k,A,B;
 8 
 9 LL pow_mod(LL p, LL k,int mod)       //(p^k)%mod
10 {
11     LL ans = 1;
12     while(k) {
13         if (k & 1) ans = ans * p % mod;
14         p = (LL)p*p % mod;
15         k >>= 1;
16     }
17     return ans;
18 }
19 
20 void divide()
21 {
22     k=1;
23     /*常规做法:分解整数A (A为非质数)*/
24     for(int i=2; i*i<=A;)  //根号法+递归法
25     {
26         if(A%i==0)
27         {
28             p[k]=i;
29             n[k]=0;
30             while(!(A%i))
31             {
32                 n[k]++;
33                 A/=i;
34             }
35             k++;
36         }
37         if(i==2)  //奇偶法
38             i++;
39         else
40             i+=2;
41     }
42     /*特殊判定:分解整数A (A为质数)*/
43     if(A!=1)
44     {
45         p[k]=A;
46         n[k++]=1;
47     }
48     k--;
49 }
50 
51 LL calc(LL p,LL n)  //递归二分求 (1 + p + p^2 + p^3 +...+ p^n)%mod
52 {                          //奇数二分式 (1 + p + p^2 +...+ p^(n/2)) * (1 + p^(n/2+1))
53     if(n==0)               //偶数二分式 (1 + p + p^2 +...+ p^(n/2-1)) * (1+p^(n/2+1)) + p^(n/2)
54         return 1;
55     if(n%2)  //n为奇数,
56         return (calc(p,n/2)*(1+pow_mod(p,n/2+1,P)))%P;
57     else     //n为偶数
58         return (calc(p,n/2-1)*(1+pow_mod(p,n/2+1,P))+pow_mod(p,n/2,P))%P;
59 }
60 
61 int main()
62 {
63     //freopen("in.txt","r",stdin);
64     while (cin>>A>>B)
65     {
66         divide();
67         LL sum=1;
68         for (LL i=1;i<=k;i++)
69         {
70             LL tm=calc(p[i],B*n[i]);
71             sum=(sum*tm)%P;
72         }
73         cout<<sum<<endl;
74     }
75     return 0;
76 }

 

posted on 2014-11-03 17:38  Pentium.Labs  阅读(176)  评论(0编辑  收藏  举报



Pentium.Lab Since 1998