1009: [HNOI2008]GT exam Time limit:1 Sec Memory limit:162 MB
submit:2154 solved:1327
[Submit] [Status] [Discuss] Description
Ashen ready to enroll in the GT exam, the ticket number is n-digit x1x2 .... Xn (0<=xi<=9), he does not want to appear on the ticket number of unlucky figures. His unlucky math a1a2 ... AM (0<=ai<=9) has M-bit, does not appear to refer to x1x2 ... The xn does not have exactly a paragraph equal to A1A2 ... Am. A1 and X1 can be 0
Input
The first line enters N,m,k. The next line is to enter the number of M bits. 100% data n<=10^9,m<=20,k<=1000 40% data n<=1000 10% data n<=6
Output
Ashen want to know how many kinds of numbers do not appear unlucky numbers, the result of output modulus K redundancy.
Sample Input4 3 100
111Sample OutputBayiHINT Source
The problem: I am very sad to do this question ... is AC (KMP) +DP
Turn over so many of the solving or CJK speak the best ... Please allow me to turn around ...
Dynamic planning on a string:
In order to process the ticket number of each person,
Set F[I][J]: The number of the first I position in the first I position after J-bit and the number of the first J phase of the unlucky numbers at the same time.
So the answer ans=f[n][0]+f[n][1]+...+f[n][m-1]
F[I][J] The exact meaning of:
1.F[I][J] indicates that each scheme is not only related to the subsequent J-bit, but also that it does not contain an unlucky number
2. For the avoidance of repetition, each scheme indicated by F[I][J] does not contain a suffix that is longer than J and has the same prefix as the unlucky number.
Otherwise it will appear: from 1 to M marking, when the number of unlucky is 123124, the scenario of the F[i][2] count scheme contains the scenario of the f[i][5] count
State transitions:
F[I][J] can only be obtained by f[i-1][k], which is equivalent to filling the i-1 bit, after the suffix K (long to K suffixes) after adding a new num, then this I-digit number of the same as the number of unlucky prefixes the longest suffix is: suffix j
I>=1: F[i][j]=f[i-1][0]*a[0][j]+f[i-1][1]*a[1][j]+...+f[i-1][m-1]*a[m-1][j]
For example: or suppose the unlucky number is 123124, then f[i][3]=f[i-1][2]+f[i-1][5], because f[i-1][2] at the end of the *****12 can not be **12312, so need f[i-1][5] supplement
But if the unlucky number is 123123, then f[i][3]=f[i-1][2], because the *****123 at the end of f[i][3] cannot be **123123
I==0: f[0][0]=1,f[0][Other]=0
Which, a[k][j] means that the above mentioned Num can take a few values, can be preprocessed with the KMP algorithm, it is a matrix
So that we can count them without a heavy leak.
Another matrix acceleration: F[i][j] The method is a linear homogeneous recursion, can be constructed into a matrix, and then add a speed.
This problem is going to leave a hole ... Because I don't know qaq.
1#include <iostream>2#include <cstdio>3#include <cmath>4#include <algorithm>5#include <queue>6#include <cstring>7 #definePAU Putchar (")8 #defineENT Putchar (' \ n ')9 using namespacestd;Ten Const intmaxn= -; One intN,MOD,LEN,NXT[MAXN];CharSTR[MAXN]; A structmatrix{intF[maxn][maxn];matrix () {memset (f),0,sizeof(f));}} M,ans; -Matrixoperator*(ConstMatrix&a,Constmatrix&b) { - Matrix C; the for(intI=0; i<len;i++) - for(intj=0; j<len;j++) - for(intk=0; k<len;k++) -C.f[i][j]= (C.f[i][j]+a.f[i][k]*b.f[k][j])%MoD; + returnC; - } + voidKMP () { A intj=0; nxt[1]=0; at for(intI=2; i<=len;i++){ - while(j&&str[j+1]!=str[i]) j=Nxt[j]; - if(str[j+1]==str[i]) j++;nxt[i]=J; -}return; - } - voiddp () { in for(intI=0; i<len;i++) - for(intj=0;j<Ten; j + +){ to intK; + for(K=i;k;k=nxt[k])if(str[k+1]-'0'==J) Break; - if(str[k+1]-'0'==J) k++; theM.f[i][k]= (m.f[i][k]+1)%MoD; * } $ return;Panax Notoginseng } - voidPow () { the for(intI=0; i<len;i++) ans.f[i][i]=1; + for(; n;n>>=1, m=m*m)if(n&1) Ans=ans*m;return; A } theInlineintRead () { + intx=0, sig=1;CharCh=GetChar (); - while(!isdigit (CH)) {if(ch=='-') sig=-1; ch=GetChar ();} $ while(IsDigit (CH)) x=Ten*x+ch-'0', ch=GetChar (); $ returnx*Sig; - } -InlinevoidWriteintx) { the if(x==0) {Putchar ('0');return;}if(x<0) Putchar ('-'), x=-x; - intlen=0, buf[ the]; while(x) buf[len++]=x%Ten, x/=Ten;Wuyi for(inti=len-1; i>=0; i--) Putchar (buf[i]+'0');return; the } - intMain () { WuN=read (); Len=read (); Mod=read (); scanf ("%s", str+1); KMP ();dp();p ow (); - intres=0; for(intI=0; i<len;i++) res= (res+ans.f[0][i])%MoD; About write (res); $ return 0; -}
BZOJ 1009 [HNOI2008]GT Exam