求A^B的所有约数和 POJ1845

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5
 6 using namespace std;
 7
 8 long long arr1[100000];
 9 long long MOD=9901;
10
11 long long multi(long long a,long long b)
12 {
13     if(b==0)
14         return 1;
15     if(b==1)
16         return a;
17     long long ret=multi(a,b/2);
18     ret=(ret*ret)%MOD;
19     if(b&1)
20         ret=ret*a%MOD;
21     return ret;
22 }
23
24 long long fsum(long long p,long long n)  //递归二分求 (1 + p + p^2 + p^3 +...+ p^n)%mod
25 {                          //奇数二分式 (1 + p + p^2 +...+ p^(n/2)) * (1 + p^(n/2+1))
26     if(n==0)               //偶数二分式 (1 + p + p^2 +...+ p^(n/2-1)) * (1+p^(n/2+1)) + p^(n/2)
27         return 1;
28     if(n%2)  //n为奇数,
29         return (fsum(p,n/2)*(1+multi(p,n/2+1)))%MOD;
30     else     //n为偶数
31         return (fsum(p,n/2-1)*(1+multi(p,n/2+1))+multi(p,n/2))%MOD;
32 }
33
34 int main()
35 {
36     long long a,b;
37     while(scanf("%I64d%I64d",&a,&b)!=EOF)
38     {
39         memset(arr1,0,sizeof(arr1));
40         long long sum=a;
41         long long ans1=1;
42         double s=sqrt((double)a);
43         int num=0;
44         for(int i=2;i<=s;i++)
45         {
46             int flag=0;
47             while(sum%i==0)
48             {
49                 sum=sum/i;
50                 flag++;
51                 arr1[num]=i;
52             }
53             if(flag)
54             {
55                 flag*=b;
56                 num++;
57                 ans1=(ans1*fsum(arr1[num-1],flag))%MOD;
58            //     cout<<arr1[num-1]<<" "<<flag<<endl;
59            //     cout<<ans1<<endl;
60             }
61         }
62         if(sum!=1)
63         {
64             arr1[num]=sum;
65             ans1=(ans1*fsum(sum,b))%MOD;
66             num++;
67         }
68         cout<<ans1<<endl;
69     }
70     return 0;
71 }

求一个数的所有约数和

ans=(1+q1^1+q1^2+......+q1^k1)*(1+q2^1+q2^2+......+q2^k2)*......(1+qn^1+qn^2+......qn^kn)

此题不能用等比数列前n项和,因为要求逆元需要该数与MOD互质,而此题中MOD过小,该数可能为MOD的整数倍,所以要用二分的方法直接求

(1+p+p^2+p^3)=(1+p)*(1+p^2)

时间: 2025-01-05 23:55:48

求A^B的所有约数和 POJ1845的相关文章

数学:求一个数的真约数(因数)的个数及所有约数之和

一. 我们知道,每个自然数(不包括0和1)都有2个以上的因数,因数最少的是质数(也叫素数),质数的因数是1和它本身.非质数的自然数也叫合数,它们都含有3个以上(含3个)的因数. 1.怎样求一个数有多少个因数? 对于一个已知的自然数,要求出它有多少个因数,可用下列方法: 首先将这个已知数分解质因数,将此数化成几个质数幂的连乘形式,然后把这些质数的指数分别加一,再相乘,求出来的积就是我们要的结果. 例如:求360有多少个因数. 因为360分解质因数可表示为:360=2^3×3^2×5,2.3.5的指

hnnu 11546 Sum of f(x) (求一个数的所有约数和)

代码: #include<cstdio> #include<cstring> #define N 200000 using namespace std; long long f[N+5]; long long s[N+5]; int main() { s[0]=0; for(int i=1;i<=N;i++) { for(int j=1;j*i<=N;j++) { f[j*i]+=i; } } for(int i=1;i<=N;i++) { s[i]=s[i-1]

HDU 5211 筛法求约数

给出n个数a1,a2...an,定义函数 f[i]=j,(i<j),表示aj mod ai=0 的最小j,其中j大于i,如果不存在这样的数,则f[i]=0 求n个数所有f[]值的和 先用筛法o(nlogn)求出每个数的约数 然后每读入一个数x,先找出所有的约数,再看看之前有没有出现过这些约数. 这个回看的过程可以用一个数组维护. 维护watch[],watch[aj]=j 表示aj还没有找到函数值,如果aj是x的约数,那么说明aj的函数值为x的位置. #include<cstdio> #

数论考试题(b) 求约数的约数的最大个数

题意:求1~n范围里约数的约数的个数加起来最多的是哪个数 及其总数 题解: /* 对一个数质因数分解 首先要知道两个公式:约数的个数的公式,和约数的约数的个数的公式(详见题解) 然后发现:质因数分解后 小的次冥尽量大 会使答案更优 然后使次幂单调不升 dfs求r序列 */ #include<bits/stdc++.h> using namespace std; #define ll long long int pri[]={2,3,5,7,11,13,17,19,23,29,31,37,41,

POJ1845 数论 二分快速取余

大致题意: 求A^B的所有约数(即因子)之和,并对其取模 9901再输出. 解题思路: 应用定理主要有三个: (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

求N个数的最大公约数和最小公倍数

除了分解质因数,还有另一种适用于求几个较小数的最大公约数.最小公倍数的方法 下面是数学证明及算法实现 令[a1,a2,..,an] 表示a1,a2,..,an的最小公倍数,(a1,a2,..,an)表示a1,a2,..,an的最大公约数,其中a1,a2,..,an为非负整数.对于两个数a,b,有[a,b]=ab/(a,b),因此两个数最小公倍数可以用其最大公约数计算.但对于多个数,并没有[a1,a2,..,an]=M/(a1,a2,..,an)成立,M为a1,a2,..,an的乘积.例如:[2,

约数的个数

约数的个数 Description mmoaay小侄子今年上初中,老师出了一道求约数个数的题目,比如8的约数有1,2,4,8共4个. 当数比较小的时候可以人工算,当n较大时就难了. mmoaay嫌麻烦,现在让你编个程序来算. Input 一行一个整数.最后以0结束. Output 分别求出这些整数的约数个数,最后的0不用处理. Sample Input 81000 Sample Output 4 9 题解:求正整数378000共有多少个正约数? 解:将378000分解质因数378000=2^4×

A+B Again(在某个数中找大于m的最小约数)

A+B Again Accepted : 15   Submit : 243 Time Limit : 1000 MS   Memory Limit : 65536 KB  题目描述 上次趣味赛小明的a+b坑了不少不喜欢思考的同学,小明为了表示歉意, 这次出了道简单的a+b给大家当签到题,希望大家能开心刷题. 那么,题目来了!!! 求使得b/(a+x)为整数的最小正整数x的值. 输入 第一行是一个整数K(K≤10000),表示样例的个数. 以后每行一个样例,为两个正整数a,b(1≤a,b≤108

xtuoj A+B Again(在某个数中找大于m的最小约数)

新生赛: Accepted : 15   Submit : 243 Time Limit : 1000 MS   Memory Limit : 65536 KB  题目描述 上次趣味赛小明的a+b坑了不少不喜欢思考的同学,小明为了表示歉意, 这次出了道简单的a+b给大家当签到题,希望大家能开心刷题. 那么,题目来了!!! 求使得b/(a+x)为整数的最小正整数x的值. 输入 第一行是一个整数K(K≤10000),表示样例的个数. 以后每行一个样例,为两个正整数a,b(1≤a,b≤108). 输出