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

题目问$A^B$的所有因数和。

根据唯一分解定理将A进行因式分解可得:A = p1^a1 * p2^a2 * p3^a3 * pn^an.
A^B=p1^(a1*B)*p2^(a2*B)*...*pn^(an*B);
A^B的所有约数之和sum=[1+p1+p1^2+...+p1^(a1*B)]*[1+p2+p2^2+...+p2^(a2*B)]*[1+pn+pn^2+...+pn^(an*B)]

知道这个,问题就变成求出A的所有质因数pi以及个数n,然后$\prod(1+p_i+p_i^2+\cdots+p_i^{n-1}+p_i^n)$就行了。可以构造矩阵来求:

记$S_n=p_i+p_i^2+\cdots+p_i^{n-1}+p_i^n$

$$ \begin{bmatrix} p_i & 1 \\ 0 & 1 \end{bmatrix} \times \begin{bmatrix} S_n \\ p_i \end{bmatrix} = \begin{bmatrix} S_{n+1} \\ p_i \end{bmatrix} $$

 

$$ \begin{bmatrix} S_n \\ p_i \end{bmatrix} = \begin{bmatrix} p_i & 1 \\ 0 & 1 \end{bmatrix} ^n \times \begin{bmatrix} S_0 \\ p_i \end{bmatrix} $$

 

A忘了$\pmod {9901}$,爆intWA到头疼= =

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 struct Mat{
 5     int m[2][2];
 6 };
 7 Mat operator*(const Mat &m1,const Mat &m2){
 8     Mat m={0};
 9     for(int i=0; i<2; ++i){
10         for(int j=0; j<2; ++j){
11             for(int k=0; k<2; ++k){
12                 m.m[i][j]+=m1.m[i][k]*m2.m[k][j];
13                 m.m[i][j]%=9901;
14             }
15         }
16     }
17     return m;
18 }
19 int calu(int a,int n){
20     a%=9901;
21     Mat e={1,0,0,1},x={a,1,0,1};
22     while(n){
23         if(n&1) e=e*x;
24         x=x*x;
25         n>>=1;
26     }
27     return (e.m[0][1]*a+1)%9901;
28 }
29 bool isPrime(int n){
30     if(n<2) return 0;
31     for(int i=2; i*i<=n; ++i){
32         if(n%i==0) return 0;
33     }
34     return 1;
35 }
36 int main(){
37     int a,b;
38     scanf("%d%d",&a,&b);
39     if(isPrime(a)){
40         printf("%d",calu(a,b));
41         return 0;
42     }
43     int res=1;
44     for(int i=2; i*i<=a; ++i){
45         if(a%i) continue;
46         if(isPrime(i)){
47             int cnt=0,tmp=a;
48             while(tmp%i==0){
49                 ++cnt;
50                 tmp/=i;
51             }
52             res*=calu(i,cnt*b);
53             res%=9901;
54         }
55         if(i!=a/i && isPrime(a/i)){
56             int cnt=0,tmp=a;
57             while(tmp%i==0){
58                 ++cnt;
59                 tmp/=i;
60             }
61             res*=calu(a/i,cnt*b);
62             res%=9901;
63         }
64     }
65     printf("%d",res);
66     return 0;
67 }

 

转载于:https://www.cnblogs.com/WABoss/p/5178426.html

以下是Java解决POJ3233—矩阵幂序列问题的代码和解释: ```java import java.util.Scanner; public class Main { static int n, k, m; static int[][] A, E; public static void main(String[] args) { Scanner sc = new Scanner(System.in); n = sc.nextInt(); k = sc.nextInt(); m = sc.nextInt(); A = new int[n][n]; E = new int[n][n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { A[i][j] = sc.nextInt() % m; E[i][j] = (i == j) ? 1 : 0; } } int[][] res = matrixPow(A, k); int[][] ans = matrixAdd(res, E); printMatrix(ans); } // 矩阵乘法 public static int[][] matrixMul(int[][] a, int[][] b) { int[][] c = new int[n][n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { for (int k = 0; k < n; k++) { c[i][j] = (c[i][j] + a[i][k] * b[k][j]) % m; } } } return c; } // 矩阵快速幂 public static int[][] matrixPow(int[][] a, int b) { int[][] res = E; while (b > 0) { if ((b & 1) == 1) { res = matrixMul(res, a); } a = matrixMul(a, a); b >>= 1; } return res; } // 矩阵加法 public static int[][] matrixAdd(int[][] a, int[][] b) { int[][] c = new int[n][n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { c[i][j] = (a[i][j] + b[i][j]) % m; } } return c; } // 输出矩阵 public static void printMatrix(int[][] a) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { System.out.print(a[i][j] + " "); } System.out.println(); } } } ``` 解释: 1. 首先读入输入的n、k、m和矩阵A,同时初始化单位矩阵E。 2. 然后调用matrixPow函数出A的k次幂矩阵res。 3. 最后将res和E相加得到结果ans,并输出。 4. matrixMul函数实现矩阵乘法,matrixPow函数实现矩阵快速幂,matrixAdd函数实现矩阵加法,printMatrix函数实现输出矩阵。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值