1013. K-based Numbers. Version 3
Time limit: 0.5 second
Memory limit: 64 MB
Let’s consider
K-based numbers, containing exactly
N digits. We define a number to be valid if its
K-based notation doesn’t contain two successive zeros. For example:
Given three numbers
N,
K and
M, you are to calculate an amount of valid
K based numbers, containing
N digits modulo
M.
You may assume that 2 ≤
N,
K,
M ≤ 10
18.
Input
The numbers
N,
K and
M in decimal notation separated by the line break.
Output
The result in decimal notation.
Sample
Tags:
)
|
DP:
dp[i] = (dp[i - 1] + dp[i - 2]) * (k - 1)
但是由于n + k <= 10^18,一点一点的递推肯定超时,所以需要用到矩阵快速幂
构造一个矩阵A如下图,一个矩阵B如下图
那么A*B会发生以下奇妙的事情…………算算就知道
结果就是A^(n - 1) * B得到的矩阵的第一列相加
用矩阵快速幂很快就解出
因为模的M也是10^18级数的,容易溢出,所以用大数处理……
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
public static Matrax Fast_power(Matrax p,long k,long mod) {
Matrax re = new Matrax(1,mod);
while(k != 0) {
if(k % 2 == 1) {
re = re.mul(p);
k --;
}
else {
k /= 2;
p = p.mul(p);
}
}
return re;
}
public static void main(String[] args) {
Scanner Cin = new Scanner(System.in);
long N = Cin.nextLong();
long K = Cin.nextLong();
long M = Cin.nextLong();
Matrax aMatrax = new Matrax(M);
Matrax bMatrax = new Matrax(M);
aMatrax.matrix[0][0] = K - 1;
aMatrax.matrix[0][1] = K - 1;
aMatrax.matrix[1][1] = 0;
aMatrax.matrix[1][0] = 1;
bMatrax.matrix[0][0] = K - 1;
bMatrax.matrix[1][0] = 0;
bMatrax.matrix[1][1] = 0;
bMatrax.matrix[0][1] = 0;
aMatrax = Fast_power(aMatrax,N - 1,M);
aMatrax = aMatrax.mul(bMatrax);
System.out.println((aMatrax.matrix[0][0] + aMatrax.matrix[1][0]) % M);
}
}
class Matrax{
public long[][] matrix = new long[2][2];
public long mod;
BigInteger temp;
public Matrax(long mod) {
this.mod = mod;
}
public Matrax(int o,long mod) {
matrix[0][0] = 1;
matrix[0][1] = 0;
matrix[1][0] = 0;
matrix[1][1] = 1;
this.mod = mod;
}
public Matrax mul(Matrax m1) {
Matrax m2 = new Matrax(mod);
for(int i = 0; i < 2; i ++) {
for(int j = 0; j < 2; j ++) {
m2.matrix[i][j] = 0;
for(int k = 0; k < 2; k ++) {
temp = BigInteger.valueOf(matrix[i][k]);
temp = temp.multiply(BigInteger.valueOf(m1.matrix[k][j]));
temp = temp.mod(BigInteger.valueOf(mod));
m2.matrix[i][j] = (temp.longValue() % mod + m2.matrix[i][j] % mod) % mod;
}
m2.matrix[i][j] %= mod;
}
}
return m2;
}
}