Elegant StringTime Limit: 1000 msMemory Limit: 65536KB64-bit integer IO format: % lld Java class name: Main
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 (random SIVE ). please calculate function (n, k ). inputInput starts with an integer T (T ≤ 400), denoting the number of test cases. each case contains two integers, n and k. n (1 ≤ n ≤ 1018) represents the length of the strings, and k (1 ≤ k ≤ 9) represents the biggest digit in the string. outputFor 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 Input21 17 6 Sample OutputCase #1: 2 Case #2: 818503Source2014 ACM-ICPC Beijing Invitational Programming Contest question
When I was playing in Beijing, I read the wrong question... The meaning is that a string with n length only uses (0, 1, 2,..., k) Numbers (k + 1. If none of the substrings in this string appear (0, 1, 2 ,..., k. Ask how many elegant strings are in all strings whose lengths are n (k + 1) digits.
For example, a string ("112345678910") is an elegant string, but a string ("963852741023") is not an elegant string, because the latter has a substring ("9638527410 ") is an arrangement.
The correct idea is to change the direction of thinking! Try to construct a string instead of directly using the exclusion principle.
Set n and k to 6 and 3 respectively.
Suppose this string is an elegant string, then all the substrings of this string with a length of 4 (= k + 1) must not appear (0, 1, 2, 3).
Let me assume that I have constructed a substring ("023"). If I want this string to be an elegant one, the next character will not be "1 ". Because once "1" is obtained, there is an arrangement...
Then I thought about it. If the substring is ("02"), there are two cases. The first one is to select a dangerous string with a length of three from 1 and 3. Why is it a dangerous string? Because the next character must not be 1 to ensure that the entire string is an elegant string. Of course, the second case is to select 0 and 2, which is equivalent to the fact that this sub-string is secure (almost secure.
So it is a planning problem.
When dp [I] [j] is used to indicate the number of j-bit security when the string is increased to the I-bit.
Transfer equation:
Therefore, it is the calculation of the Rapid power of the matrix.
Now that we are all at this step, the matrix is very easy to write: <喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> VcD4KPHA + pgltzybzcm9 "http://www.2cto.com/uploadfile/Collfiles/20140523/20140523091449228.gif" alt = "\">
The final result is
Res is the answer.
Sample Code
/*****@author Shen*@title ±±¾©ÑûÇëÈüE*/#include
#include
#include
#include
#include using namespace std;typedef long long int64;const int MAXN = 11;const int MAXM = 11;const int Mod = 20140518;struct Matrax{ int n,m; int64 mat[MAXN][MAXM]; Matrax():n(-1),m(-1){} Matrax(int _n,int _m):n(_n),m(_m){ memset(mat,0,sizeof(mat)); } void Unit(int _s){ n=_s; m=_s; for (int i = 0; i < n; i++){ for (int j = 0; j < n; j++){ mat[i][j] = (i == j)? 1: 0; } } } void print(){ printf("n = %d, m = %d\n", n, m); for (int i = 0; i < n; i++){ for (int j = 0; j < m; j++) printf("%8d", mat[i][j]); printf("\n"); } }};Matrax add_mod(const Matrax& a,const Matrax& b,const int64 mod){ Matrax ans(a.n,a.m); for (int i = 0; i < a.n; i++){ for (int j = 0; j < a.m; j++){ ans.mat[i][j] = (a.mat[i][j] + b.mat[i][j]) % mod; } } return ans;}Matrax mul(const Matrax& a,const Matrax& b){ Matrax ans(a.n, b.m); for (int i = 0; i < a.n; i++){ for (int j = 0; j < b.m; j++){ int64 tmp = 0; for (int k = 0; k < a.m; k++){ tmp += a.mat[i][k] * b.mat[k][j]; } ans.mat[i][j] = tmp; } } return ans;}Matrax mul_mod(const Matrax& a, const Matrax& b, const int mod){ Matrax ans(a.n, b.m); for (int i = 0; i < a.n; i++){ for (int j = 0; j < b.m; j++){ int64 tmp = 0; for (int k = 0; k < a.m; k++){ tmp += (a.mat[i][k] * b.mat[k][j]) % mod; } ans.mat[i][j] = tmp % mod; } } return ans;}Matrax pow_mod(const Matrax& a, int64 k, const int mod){ Matrax p(a.n,a.m), ans(a.n,a.m); p = a; ans.Unit(a.n); if (k==0) return ans; else if (k==1) return a; else { while (k){ if (k & 1){ ans=mul_mod(ans, p, mod); k--; } else { k /= 2; p = mul_mod(p, p, mod); } } return ans; }}int64 n;int k, t, tt;void solve(){ cin >> n >> k; Matrax ans(k, 1); //tmp = cef ^ (n - 1); //ans = tmp * beg; //res = ans.mat[0][0]; Matrax cef(k, k); for (int i = 0; i < k; i++) for (int j = 0; j <= i; j++) cef.mat[i][j] = 1; for (int i = 0; i < k - 1; i++) cef.mat[i][i + 1] = k - i; //cef.print(); Matrax beg(k, 1); for (int i = 0; i < k; i++) beg.mat[i][0] = k + 1; Matrax tmp(k, k); tmp = pow_mod(cef, n - 1, Mod); //tmp.print(); ans = mul_mod(tmp, beg, Mod); int res = ans.mat[0][0]; printf("Case #%d: %d\n", ++tt, res);}int main(){ cin >> t; while (t--) solve(); return 0;}