Topic links
Test Instructions: There is a different character, each character has an infinite number, requires the use of this K character to construct two length n strings A and B, so that the longest common part of a string and b string length is just m, ask scheme
Analysis:
Intuition is DP.
But when I saw that N was big, but M was small,
found that this problem DP is not appropriate, so think may be some kind of combinatorial mathematics problems can be directly calculated
See the solved me, suddenly, for this kind of data, you can consider the matrix fast power optimization of DP
The first thing to think about is a linear recursive DP formula
The most intuitive idea is dp[i][j] = the number of scenarios with the longest matching length of J before the first position
But if you think about it, the definition of such a state is not a good transfer, so change a way of thinking
Define DP[I][J] = The number of schemes with a length of j for a matched string ending with the first I character.
There are transfers
Dp[i][0] = (Dp[i-1][0] + dp[i-1][1] + (...) + dp[i-1][m]) * k * (k-1) (k * (k-1) meaning is a, B string the number of the first character of the program)
DP[I][J] = dp[i-1][j-1] * k (j≤i)
Then try to construct the matrix, referencing the link here
But pay attention to the DP meaning here, the answer is not at last Dp[n][m]
Dp[n][0] + dp[n][1] + ... + dp[n][m] can be seen as the number of scenarios matching length ≤m to nth position
So if you can get the number of schemes that match the length of ≤m-1, you can get the number of matching lengths just as M.
So do two times the matrix fast power can
#include <bits/stdc++.h>#defineLL Long Long#defineULL unsigned long Long#defineSCL (i) scanf ("%lld", &i)#defineSCLL (i, J) scanf ("%lld%lld", &i, &j)#defineSclll (I, J, K) scanf ("%lld%lld%lld", &i, &j, &k)#defineScllll (I, J, K, L) scanf ("%lld%lld%lld%lld", &i, &j, &k, &l)#defineSCS (i) scanf ("%s", I)#defineSCI (i) scanf ("%d", &i)#defineSCD (i) scanf ("%lf", &i)#defineScIl (i) scanf ("%i64d", &i)#defineScii (i, J) scanf ("%d%d", &i, &j)#defineSCDD (i, J) scanf ("%lf%lf", &i, &j)#defineScill (i, J) scanf ("%i64d%i64d", &i, &j)#defineSCIII (I, J, K) scanf ("%d%d%d", &i, &j, &k)#defineSCDDD (I, J, K) scanf ("%lf%lf%lf", &i, &j, &k)#defineScilll (I, J, K) scanf ("%i64d%i64d%i64d", &i, &j, &k)#defineSCIIII (I, J, K, L) scanf ("%d%d%d", &i, &j, &k, &l)#defineSCDDDD (I, J, K, L) scanf ("%lf%lf%lf%lf", &i, &j, &k, &l)#defineScillll (I, J, K, L) scanf ("%i64d%i64d%i64d%i64d", &i, &j, &k, &l)#defineLson L, M, rt<<1#defineRson m+1, R, rt<<1|1#defineLowbit (i) (I & (i))#defineMem (i, J) memset (i, J, sizeof (i))#defineFIR First#defineSEC Second#defineVI vector<int>#defineINS (i) Insert (i)#definePB (i) push_back (i)#definePII Pair<int, int>#defineVL Vector<long long>#defineMK (i, J) Make_pair (I, J)#defineAll (i) I.begin (), I.end ()#definePLL Pair<long Long, long long>#define_time 0#define_input 0#define_output 0clock_t START, END;void__sttime ();void__entime ();void__ioput ();using namespacestd;Const intMAXN = 1e5 +Ten;ConstLL mod = 1e9 +7;structmat{LL val[ A][ A]; intsz; MAT () {}; MAT (int_SZ) {sz = _SZ; Memset (Val,0,sizeof(Val)); } Friend MAToperator* (ConstMAT & A,ConstMAT &B) {MAT C (A.SZ); for(intK =1; K <= C.sz; k++) for(inti =1; I <= C.sz; i++){ if(A.val[i][k] = =0)Continue; for(intj =1; J <= C.sz; J + +) {C.val[i][j]= C.val[i][j] + a.val[i][k] * B.val[k][j]%MoD; if(C.val[i][j] >= MoD) C.VAL[I][J]-=MoD; } } returnC; }}; Mat Pow_mod (Mat A, LL b) {mat ret (A.SZ); for(intI=1; i<=ret.sz; i++) Ret.val[i][i] =1; while(b) {if(B &1) ret = RET *A; A= A *A; b>>=1; }returnret;} LL Cal (intNintMintk) {MAT A (M+1); for(intI=1; i<=a.sz; i++) a.val[1][i] = 1LL * k * (K-1); for(intI=2; i<=a.sz; i++) a.val[i][i-1] = k *1LL; A=Pow_mod (A, N); LL ret=0; for(intI=1; i<=a.sz; i++) ret= (ret + a.val[i][1]) %MoD; returnret;}intMainvoid) {__sttime (); __ioput (); intncase; SCI (ncase); while(ncase--){ intN, M, K; SCIII (n, M, k); printf ("%lld\n", (Cal (N, M, K)-Cal (N, M.1, k) + MoD)%MoD); }__entime ();return 0;}void__sttime () {#if_timeSTART=clock (); #endif}void__entime () {#if_timeEND=clock (); Cerr<<"Execute time ="<< (Double) (End-start)/clocks_per_sec<<Endl; #endif}void__ioput () {#if_inputFreopen ("In.txt","R", stdin); #endif #if_outputFreopen ("OUT.txt","W", stdout); #endif}
View Code
HDU 5863 Cjj's string game (16 G, Matrix fast Power optimization linear recursive DP)