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 }
时间: 2024-10-10 14:21:02

poj 1845 数论综合的相关文章

poj 1845 数论(逆元或者分治)

分治求等比数列和的模: 1 #include <iostream> 2 using namespace std; 3 4 typedef long long ll; 5 6 ll pow_mod( ll a, ll b, ll mod ) 7 { 8 ll ans = 1, w = a % mod; 9 while ( b ) 10 { 11 if ( b & 1 ) 12 { 13 ans = ans * w % mod; 14 } 15 b = b >> 1; 16 w

POJ 1845 - Sumdiv ( 数论 + 唯一分解定理 + 快速幂取模 )

POJ 1845 - Sumdiv ( 数论 + 唯一分解定理 + 快速幂取模 ) 这是一道数论的好题,需要较好的数学基础 题意: 给定A,B,求A^B的所有因数的和,再MOD 9901 分析: 这里用到了数论当中相当一部分知识 a. 唯一分解定理 任何一个整数都可以分解为若干个素数的幂的乘积的形式 A = ( p1 ^ q1 + p2 ^ q2 + ..... + pn ^ qn ) p为素数 A^B = ( p1 ^ (q1*B) + p2 ^ (q2*B) + ..... + pn ^ (

poj 1845 Sumdiv (算术基本定理求一个数因子和)

求一个数的所有因子和可以用算术基本定理,下面是它的两个重要应用: (1)一个大于1的正整数N,如果它的标准分解式为: N=(P1^a1)*(P2^a2)......(Pn^an) 那么它的正因数个数为(1+a1)(1+a2).....(1+an). (2) 它的全体正因数之和为d(N)=(1+p1+...p1^an)(1+p2+...p2^a2)...(1+pn+...+pn^an) 和求一个数正因数个数的方法类似. 可以先打表出sqrt(n)以内的所有素数(当然也可以不打表),因为n的素因数中

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

[POJ 1845] Sumdiv 用的东西挺全 最主要通过这个题学了约数和公式跟二分求等比数列前n项和 另一种小优化的整数拆分  整数的唯一分解定理: 随意正整数都有且仅仅有一种方式写出其素因子的乘积表达式. A=(p1^k1)*(p2^k2)*(p3^k3)*....*(pn^kn)   当中pi均为素数 约数和公式: 对于已经分解的整数A=(p1^k1)*(p2^k2)*(p3^k3)*....*(pn^kn) 有A的全部因子之和为 S = (1+p1+p1^2+p1^3+...p1^k1

POJ 1845 Sumdiv【同余模运算+递归求等比数列和+快速幂运算】

快速幂运算在第一次训练时候就已经遇到过,这里不赘述 同余模运算也很简单,这里也不说了,无非是(a+b)%m (a*b)%m 把m弄到里面变成(a%m+b%m)%m   (a%m*b%m)%m 今天学的最重要的还是递归二分求等比数列 题目大意是给出A和B,求A^B的约数和 解这个题,首先,对A进行素因子分解得到 (PI(pi^ai))^B 然后我们有约数和公式: 对A=PI(p1^k1) A的所有因子之和为S = (1+p1+p1^2+p1^3+...p1^k1) * (1+p2+p2^2+p2^

poj 1845 Sumdiv (同余定理,快速幂取余)

链接:poj 1845 题意:求A^B的所有因子的和对9901取余后的值 如:2^3=8,8的因子有 1,2,4,8,所有和为15,取余后也是15 应用定理主要有三个: (1)整数的唯一分解定理: 任意正整数都有且只有一种方式写出其素因子的乘积表达式. A=(p1^k1)*(p2^k2)*(p3^k3)*....*(pn^kn)   其中pi均为素数 (2)约数和公式: 对于已经分解的整数A=(p1^k1)*(p2^k2)*(p3^k3)*....*(pn^kn) 有A的所有因子之和为 S = 

poj 1845(等比数列前n项和及快速幂)

Sumdiv Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 13959   Accepted: 3433 Description Consider two natural numbers A and B. Let S be the sum of all natural divisors of A^B. Determine S modulo 9901 (the rest of the division of S by 99

POJ【数论/组合/博弈论】

 POJ[数论/组合/博弈论]题目列表 POJ[数论/组合/博弈论]题目列表 原来的列表比较水,今天换了一个难一些的列表,重新开始做~ 红色的代表已经AC过,蓝色的代表做了但是还没过.这句话貌似在我空间里的每份列表里都有额. 博弈论 POJ 2234 Matches Game POJ 2975 Nim POJ 2505 A multiplication game POJ 1067 取石子游戏 POJ 2484 A Funny Game POJ 2425 A Chess Game POJ 29

POJ 1845 Sumdiv (快速分解因式+快速幂取模)

题目地址:POJ 1845 转载自:http://blog.csdn.net/lyy289065406/article/details/6648539 大致题意: 求A^B的所有约数(即因子)之和,并对其取模 9901再输出. 解题思路: 要求有较强 数学思维 的题 应用定理主要有三个: 要求有较强 数学思维 的题 应用定理主要有三个: (1)   整数的唯一分解定理: 任意正整数都有且只有一种方式写出其素因子的乘积表达式. A=(p1^k1)*(p2^k2)*(p3^k3)*....*(pn^