Elegant String
We define a kind of strings as elegant string: among all the substrings of an elegant string, none of them is a permutation of "0, 1,…, k".
Let function(n, k) be the number of elegant strings of length n which only contains digits from 0 to k (inclusive). Please calculate function(n, k).
Input
Input starts with an integer T (T ≤ 400), denoting the number of test cases.
Each case contains two integers, n and k. n (1 ≤ n ≤ 10
18) represents the length of the strings, and k (1 ≤ k ≤ 9) represents the biggest digit in the string.
Output
For each case, first output the case number as "
Case #x: ", and x is the case number. Then output function(n, k) mod 20140518 in this case.
Sample Input
2 1 1 7 6
Sample Output
Case #1: 2 Case #2: 818503
用F[j][i]表示结尾长度为j的有i个连续的不同的数字的种数(只有F[j][k+1]表示的长度为j的字符串中非法的有F[j][k+1]种);
1).F[j][k+1]=F[j-1][k]+F[j-1][k+1]*(k+1).
2).1<i<=k: F[j][i]=sigma(F[j-1][r])(i<=r<=k) + F[j-1][i-1]*(k+1-(i-1));
3).i==1:F[j][1]=sigma(F[j-1][r])(1<=r<=k)
1).F[j][k+1]=F[j-1][k]+F[j-1][k+1]*(k+1).
2).1<i<=k: F[j][i]=sigma(F[j-1][r])(i<=r<=k) + F[j-1][i-1]*(k+1-(i-1));
3).i==1:F[j][1]=sigma(F[j-1][r])(1<=r<=k)
参考 Zhuhuangjian的专栏
typedef long long LL ;
const LL mod = 20140518 ;
int n ;
struct Mat{
LL x[11][11] ;
Mat(){ memset(x , 0 , sizeof(x)) ; }
Mat(int){
memset(x , 0 , sizeof(x)) ;
for(int i = 1 ; i <= n ; i++) x[i][i] = 1 ;
}
};
Mat operator * (Mat A , Mat B){
Mat s ;
for(int i = 1 ; i <= n ; i++){
for(int j = 1 ; j <= n ; j++){
if(A.x[i][j] == 0) continue ;
for(int k = 1 ; k <= n ; k++){
s.x[i][k] = (s.x[i][k] + A.x[i][j] * B.x[j][k] % mod) % mod ;
}
}
}
return s ;
}
Mat operator ^ (Mat x , LL y){
Mat s(1) ;
for(;y;y>>=1){
if(y&1) s = s * x ;
x = x * x ;
}
return s ;
}
Mat getA(int k){
n = k + 1 ;
Mat A ; int i , j ;
for(i = 1 ; i <= k ; i++) A.x[1][i] = 1 ;
for(i = 2 ; i <= k ; i++){
for(j = i ; j <= k ; j++) A.x[i][j] = 1 ;
A.x[i][i-1] = (k+1) - (i-1) ;
}
A.x[k+1][k] = 1 , A.x[k+1][k+1] = k+1 ;
return A ;
}
LL Pow(LL x , LL y){
LL s = 1 ;
for(;y;y>>=1){
if(y&1){ s *= x ; s %= mod ; }
x *= x ; x %= mod ;
}
return s ;
}
int main(){
int t , T = 1 , k ;
LL N , s ;
cin>>t ;
while(t--){
scanf("%lld%d" ,&N , &k) ;
printf("Case #%d: " , T++) ;
if(N == 1){ printf("%d\n" , k+1) ; continue ;}
s = Pow(LL(k+1) , N) ;
Mat A = getA(k) ;
A = A ^ (N-1) ;
s -= (A.x[k+1][1] * (LL)(k+1)) % mod ;
s = (s + mod) % mod ;
printf("%lld\n" , s) ;
}
return 0 ;
}