bzoj 1009: [HNOI2008]GT考试(dp+kmp+矩阵快速幂)

来源:互联网 发布:单片机电子时钟原理图 编辑:程序博客网 时间:2024/05/29 04:24

1009: [HNOI2008]GT考试

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 3932  Solved: 2398
[Submit][Status][Discuss]

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 100
111

Sample Output

81


如果n很小的话,显然直接dp就好了

dp[i][j]表示身份证号的前i个数,最后j个数和不吉利数的前j位相同的合法情况数

不过注意这里的j一定是要是最长前缀

例如不吉利数2351237,  当前身份证前9个数是888235123,那么这属于dp[9][6]而不是dp[9][2]

那么怎么转移呢


很好想到dp[i][j] = dp[i][j-1],但仍然不一定

还是不吉利数2351237,dp[i][3] = dp[i-1][2]+dp[i-1][6],为什么还要加个dp[i-1][6]呢?

因为235123后面接5之后变为2351235,原本能匹配长度为6的前缀,加上5之后刚好只能匹配长度为3的前缀了

而吉利数是2351235的话就不能加了,因为dp[i-1][6]后面接个5应该算在dp[i-1][7]中(可以匹配长度为7的前缀)!


所以dp[i][j] = ∑(dp[i-1][k]*p[k][j])  (0<=k<=m-1)

其中p[k][j]表示不吉利数前k个字符加上某个字符后最多能匹配不吉利数的前j个字符,问有多少种可添加字符

比如不吉利数2351237,p[6][3]==1因为235123后面接个5变为2351235,最多能匹配前三个字符235,

p[1][0]==8,因为2后面只要不接3就一定不是不吉利数的任何前缀

这也意味着一般来讲只有j==0的时候p[i][j]会大于1,其他时候要不是0要不是1

再举个例子:不吉利数1235123723构成的p[][]矩阵(行和列都是0到m-1即0到9)

9  1  0  0  0  0  0  0  0  0

8  1  1  0  0  0  0  0  0  0

8  1  0  1  0  0  0  0  0  0

8  1  0  0  1  0  0  0  0  0

9  0  0  0  0  1  0  0  0  0

8  1  0  0  0  0  1  0  0  0

8  1  0  0  0  0  0  1  0  0

7  1  0  0  1  0  0  0  1  0

8  1  0  0  0  0  0  0  0  1

8  1  0  0  0  0  0  0  0  0

上面p[][]矩阵的第一行刚好就是dp[1][i]!而dp[2][i] = ∑(dp[1][k]*p[k][j]) (0<=k<=m-1)

是不是很像矩阵乘法?所以最后答案就是矩阵p[][]自乘n次后第一行的和

至于如何求出p矩阵?kmp瞎搞搞就好了


#include<stdio.h>#include<string.h>int n, mod;typedef struct{int i, j;int a[32][32];void init(){memset(a, 0, sizeof(a));}void unit(){memset(a, 0, sizeof(a));for(i=1;i<=n;i++)a[i][i] = 1;}}Matrix;Matrix Jz;Matrix Powto(Matrix p, int k);Matrix Jjcf(Matrix p1, Matrix p2);int main(void){int k, p, q, i, ans, net[25];char str[25], j;while(scanf("%d%d%d", &k, &n, &mod)!=EOF){Jz.init();scanf("%s", str+1);memset(net, 0, sizeof(net));p = 0, q = 1, net[1] = 0;while(q<=n){if(p==0 || str[p]==str[q]){p++, q++;if(str[p]==str[q])net[q] = net[p];elsenet[q] = p;}elsep = net[p];}Jz.a[1][1] = 9, Jz.a[1][2] = 1;for(i=1;i<=n-1;i++){for(j='0';j<='9';j++){p = i+1;while(str[p]!=j && p!=0)p = net[p];Jz.a[i+1][p+1]++;}}Jz = Powto(Jz, k);ans = 0;for(i=1;i<=n;i++)ans = (ans+Jz.a[1][i])%mod;printf("%d\n", ans);}return 0;}Matrix Powto(Matrix p, int k){Matrix bg, E;E.unit();if(k==0)return E;if(k==1)return p;bg = Powto(p, k>>1);bg = Jjcf(bg, bg);if((k&1)==1)bg = Jjcf(bg, p);return bg;}Matrix Jjcf(Matrix p1, Matrix p2){Matrix pe;int i, j, k;memset(pe.a, 0, sizeof(pe.a));for(i=1;i<=n;i++){for(j=1;j<=n;j++){for(k=1;k<=n;k++)pe.a[i][j] = (pe.a[i][j]+p1.a[i][k]*p2.a[k][j])%mod;}}return pe;}/*10000 7 1232351237*/


阅读全文
1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 海外直邮身份证过期了怎么办 买车的人不过户怎么办 天猫精灵球泡离线怎么办 花呗被骗了2万怎么办 天猫公司变更地址发票怎么办 支付宝自助解限怎么办 支付宝16岁限额怎么办 支付宝提不了现怎么办 支付宝余额受限需要身份证怎么办 微信被骗了6000怎么办 被代运营骗了该怎么办 淘宝店铺过节放假无人打理怎么办 淘宝店太久没打理出现未开店怎么办 淘宝店关了售后怎么办 发货运单号发错了怎么办 天猫积分为零怎么办 山东聊城小型车脱审一年怎么办? 廉租房如果夫妻离婚怎么办 淘宝客服不给退货怎么办 天猫客服打字慢怎么办 京东买的kindle坏了怎么办 欧巴怎么办韩语怎么写 聚划算淘宝口令打不开怎么办 道聚城白银礼包下架怎么办 聚星输了很多钱怎么办 弹力运动裤被烟烧了个洞怎么办 生完宝宝胯宽怎么办 黑色纯棉裤子洗的发白怎么办 金盾保险柜密码忘了怎么办 装修好的房子漏水怎么办 刚装修的房子墙面开裂怎么办 刚装修的房子有味道怎么办 代销产品规格填写不完整怎么办 我的信息被泄露怎么办 进入不良网站手机发信息怎么办 发不良信息被停机了怎么办 手机qq登录显示被冻结怎么办 qq账户被冻结了怎么办 qq钱包账户被永久冻结怎么办 怎么办转让费还没给我 收钱吗不能抵用红包怎么办