国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

BZOJ 1009 [HNOI2008] GT考試

2019-11-06 06:32:08
字體:
來源:轉載
供稿:網友

Description

  阿申準備報名參加GT考試,準考證號為N位數X1X2....Xn(0<=Xi<=9),他不希望準考證號上出現不吉利的數字。他的不吉利數學A1A2...Am(0<=Ai<=9)有M位,不出現是指X1X2...Xn中沒有恰好一段等于A1A2...Am. A1和X1可以為0

Input

  第一行輸入N,M,K.接下來一行輸入M位的數。 N<=10^9,M<=20,K<=1000

Output

  阿申想知道不出現不吉利數字的號碼有多少種,輸出模K取余的結果.

Sample Input

4 3 100111

Sample Output

81

HINT

Source

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

KMP+矩陣乘法優化DP+快速冪~

(其實不用KMP也可以吧……20的數據用KMP有種雞肋的感覺……)

先用KMP求出不吉利串的next[i],方便跳轉。

轉移方程比較容易想到:用f[i][j]表示目前匹配到第i位,已經有j位與不吉利串的后綴吻合的種類數,如果下一位能匹配就直接++,否則用next[i]跳轉轉移。

但是n比較大,用矩陣乘法+快速冪優化一下,構造b矩陣,第i位能跳轉到字符j+'0'時,b[i][j]++,然后用基礎矩陣a(就是對角線為1其余全為0)做快速冪就可以了,最后統計所有沒有匹配出串的答案f[i][0]即可~

#include<cstdio>#include<cstring>#include<iostream>using namespace std;int n,m,modd,k,next[21],ans;char s[21];struct node{	int a[21][21];}a,b;int read(){	int totnum=0;char ch=getchar();	while(ch<'0' || ch>'9') ch=getchar();	while(ch>='0' && ch<='9') {totnum=(totnum<<1)+(totnum<<3)+ch-'0';ch=getchar();}	return totnum;}node Operator * (node u,node v){	node z;	for(int i=0;i<m;i++)	  for(int j=0;j<m;j++)	  {	  	z.a[i][j]=0;	  	for(int kkz=0;kkz<m;kkz++) z.a[i][j]=(z.a[i][j]+u.a[i][kkz]*v.a[kkz][j])%modd;	  }	return z;}int main(){	n=read();m=read();modd=read();scanf("%s",s+1);	for(int i=2;i<=m;i++)	{		while(k && s[i]!=s[k+1]) k=next[k];		if(s[i]==s[k+1]) k++;next[i]=k;	}	for(int i=0;i<m;i++)	  for(int j=0;j<=9;j++)	  {	  	k=i;	  	while(k && s[k+1]-'0'!=j) k=next[k];	  	if(s[k+1]-'0'==j) k++;	  	if(k!=m) b.a[k][i]=(b.a[k][i]+1)%modd;	  }	for(int i=0;i<m;i++) a.a[i][i]=1;	while(n)	{		if(n&1) a=a*b;		b=b*b;n>>=1;	}	for(int i=0;i<m;i++) ans=(ans+a.a[i][0])%modd;	PRintf("%d/n",ans);	return 0;}


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 嫩江县| 东丽区| 当涂县| 银川市| 湖北省| 万全县| 富宁县| 绥江县| 中卫市| 牡丹江市| 台州市| 邯郸县| 哈巴河县| 霍州市| 游戏| 法库县| 平远县| 辰溪县| 丰镇市| 泾川县| 禹城市| 宁南县| 宁强县| 河曲县| 辉南县| 涿州市| 庐江县| 启东市| 钟祥市| 永泰县| 双江| 兴义市| 济阳县| 禄劝| 万山特区| 怀远县| 綦江县| 彭山县| 雅江县| 京山县| 阳原县|