[HNOI 2008]GT考试

题目

阿申准备报名参加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

OUTPUT

81

解题报告

  这道题一开始真心没有什么思路,后来我跟两个dalao一起商(luan)谈(gao)了一个来小时,终于搞了出来= =

  首先,我们我们考虑两个串(从短到长)
  第一个串为不断增加的准考证号,第二个串为不吉利的号码,第一个串的后缀与第二个串的前缀为重复部分,那么我们很容易得出递推关系

  先扯出来,考虑两个集合,一个集合为不吉利的号码,一个集合为吉利的号码。我们只考虑后缀(正确性显然,因为长度长的串一定是由长度短的串递推过来的,所以如果前面有不吉利串,一定被前面的串卡掉了),当后缀包含了m个不吉利串,该串一定是不吉利的。那么,后缀包含0~m-1个不吉利串的前缀的串一定是吉利的。所以,我们把求不吉利的串 转化为 求 后缀包含不吉利串0~m-1 的 串 的 方案数

  然而与字符串有啥关系?
  考虑这样一个不吉利串

    123124

  当你的后缀带了2时,你怎么知道你的后几位是12还是12312?所以,加一位不吉利数不代表直接在后面加了一位。
  那么,问题来了,如何表示这些奇(chun)奇(de)怪(bu)怪(xing)的转移?
  考虑一个递推矩阵,设dp[i][j]为第i个号码匹(zhuan)配(yi)到第j个不吉利数字的方案数,设a[k][i]为k位后加一个数转移到j的方案数,我们可以轻易的得出递推关系:

      dp[i][j]=/sumdp[i-1][k]*a[k][j]   

  用KMP构造初始矩阵,矩阵快速幂得到递推结果。

  为什么是矩阵快速幂?
  这个问题很简单。我们知道,矩阵乘是这样写的:

 martrix tmp;
for(int i=;i<n;i++)
for(int j=;j<n;j++){
tmp.data[i][j]=;
for(int k=;k<n;k++){
tmp.data[i][j]+=(a.data[i][k]*b.data[k][j]);
tmp.data[i][j]%=mod;
}
}
return tmp;

  那么问题就简单起来了,考虑一个3*3的初始矩阵,第i行,第j列表示从第i位加一个数字转移到第j为数字的方案数,那么以该矩阵的平方的第一行第一列的数为例,(设初始矩阵为a,该矩阵为x):
  x[1][1]=a[1][1]×a[1][1]+a[1][2]×a[2][1]+a[1][3]×a[3][1];
  因为是平方得到的矩阵,所以代表了转移两步的状态,我们知道,x[1][1]代表了从第一位经两步转移到第一位的方案数,由加法原理可知:
  1->1(经两步)=(1->1->1)+(1->2->1)+(1->3->1)
  而又由乘法原理可知:
  1->2->1=(1->2)×(2->1)
  那么正确性就很显然了,由矩阵快速幂的递推关系可知,最终结果即为第一行的数的和
  至于KMP,把10个数字扔进去乱搞就是了= =
  记得要模k= =

 #include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n,m,mod;
char s[];
int kp[];
inline void get_kp(){
kp[]=;
kp[]=;
int k();
for(int i=;i<=m;i++){
while(k&&s[k]!=s[i-])
k=kp[k];
if(s[k]==s[i-])
k++;
kp[i]=k;
}
}
struct node{
int data[][];
node(){
memset(data,,sizeof(data));
}
node operator*(node &a){
node tmp;
for(int i=;i<m;i++)
for(int j=;j<m;j++){
tmp.data[i][j]=;
for(int k=;k<m;k++){
tmp.data[i][j]+=(data[i][k]*a.data[k][j]);
tmp.data[i][j]%=mod;
}
}
return tmp;
}
node operator*=(node &a){
*this=*this*a;
return *this;
}
}a,sing;
ostream& operator<<(ostream &out,node &a){
for(int i=;i<m;i++){
for(int j=;j<m;j++)
out<<a.data[i][j]<<' ';
out<<endl;
}
return out;
}
int main(){
scanf("%d%d%d%s",&n,&m,&mod,s);
get_kp();
for(int i=;i<m;i++)
for(int j=;j<=;j++){
int k(i);
while(k&&(j+'')!=s[k])
k=kp[k];
if(j+''==s[k])
k++;
if(k!=m){
a.data[i][k]++;
a.data[i][k]%=mod;//cout<<'*';
}
}//cout<<a<<endl;
/*for(int i=0;i<m;i++){
for(int j=0;j<m;j++)
cout<<a[i][j]<<' ';
cout<<'\n';
}*/
for(int i=;i<m;i++)
sing.data[i][i]=;
int tmp(n);
while(tmp){
if(tmp&)
sing*=a;
a*=a;
//cout<<tmp<<endl;
//cout<<a<<endl<<sing<<endl;
tmp>>=;
}
int ans();
for(int i=;i<m;i++){
ans=(ans+sing.data[][i])%mod;
//cout<<ans<<endl;
}
cout<<ans;
//while(1);
}

ps:2017-6-14 晚 讲题用题解
pss:调矩阵快调死了= =,最后发现初始矩阵求错了= =

[补档][HNOI 2008]GT考试的更多相关文章

  1. [补档][NOI 2008]假面舞会

    [NOI 2008]假面舞会 题目 一年一度的假面舞会又开始了,栋栋也兴致勃勃的参加了今年的舞会.今年的面具都是主办方特别定制的.每个参加舞会的人都可以在入场时选择一个自己喜欢的面具. 每个面具都有一 ...

  2. BZOJ 1009 HNOI 2008 GT考试 递推+矩乘

    1009: [HNOI2008]GT考试 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 3679  Solved: 2254[Submit][Statu ...

  3. [HNOI 2008]GT考试

    Description 题库链接 问你长度为 \(n\) 的可含前导零的数字串中,不含长度为 \(m\) 的子串 \(X\) 有多少个,取模. \(1\leq n\leq 10^9,1\leq m\l ...

  4. STL 补档

    STL 补档 1.vector 作用:它能够像容器一样存放各种类型的对象,简单地说,vector是一个能够存放任意类型的动态数组,能够增加和压缩数据. vector在C++标准模板库中的部分内容,它是 ...

  5. 图论补档——KM算法+稳定婚姻问题

    突然发现考前复习图论的时候直接把 KM 和 稳定婚姻 给跳了--emmm 结果现在刷训练指南就疯狂补档.QAQ. KM算法--二分图最大带权匹配 提出问题 (不严谨定义,理解即可) 二分图 定义:将点 ...

  6. [补档] 大假期集训Part.1

    新博客搭起来先补一发档... 那就从大假期集训第一部分说起好了QwQ 自己还是太菜掉回了2016级水平 day1: day1的时候来得有点晚(毕竟准高一)然后进机房发现早就开考了还没有给我题面于是搞了 ...

  7. [补档][JLOI 2017]聪明的燕姿

    [NOI 2008]假面舞会 题目 阴天傍晚车窗外 未来有一个人在等待 向左向右向前看 爱要拐几个弯才来 我遇见谁会有怎样的对白 我等的人他在多远的未来 我听见风来自地铁和人海 我排着队拿着爱的号码牌 ...

  8. 软件安装配置笔记(三)——ArcGIS系列产品安装与配置(补档)(附数据库连接及数据导入)

    在前两篇安装配置笔记之后,就忘记把其他安装配置笔记迁移过来了,真是失误失误!趁现在其他文档需要赶紧补上. 目录: 一.ArcMap 二.ArcMap连接数据库并导入数据 三.Arcgis Pro 四. ...

  9. [补档]暑假集训D8总结

    %dalao 今天有两位大佬来讲课,meaty来讲了Catalan(本来说好的莫比乌斯反演呢),聪聪来讲Splay呢 至于听课笔记= =,没来得及记= = 不过好不想上树啊,上了树就下不来了 考试 仍 ...

随机推荐

  1. WCF学习——构建一个简单的WCF应用(二)

    我们接着上一篇文章进行讲解 http://www.cnblogs.com/songjianhui/p/7060698.html 一:客户端通过添加引用调用服务 WCF应用服务被成功寄宿后,WCF服务应 ...

  2. 源码安装LNMP环境

    新装CentOS 6.7,安装默认服务版本basic server 安装顺序linux(忽略...)--> Nginx--> Mariadb--> PHP 为了不影响测试效果,首先关 ...

  3. zepto的使用方法

    有些不了解zepto的同学在刚接触的时候肯定有很多疑惑,这个东西怎么用啊,去哪里下载啊,什么时候该用什么时候不该用啊,其实我以前也是这样的.jquery使用多了那么就让我们一起来了解下zepto把. ...

  4. 出错场景是升级oracle驱动,将版本从ojdbc14升级到ojdbc6,hibernate执行原生态sql语句会报如下错误

    出错场景是升级oracle驱动,将版本从ojdbc14升级到ojdbc6,hibernate执行原生态sql语句会报如下错误:org.hibernate.MappingException: No Di ...

  5. Vulkan Tutorial 24 Descriptor pool and sets

    操作系统:Windows8.1 显卡:Nivida GTX965M 开发工具:Visual Studio 2017 Introduction 描述符布局描述了前一章节讨论过的可以绑定的描述符的类型.在 ...

  6. [leetcode-582-Kill Process]

    Given n processes, each process has a unique PID (process id) and its PPID (parent process id). Each ...

  7. centos中NAT模式下静态IP连接外网

    使用linux虚拟机时,通常会用到yum命令来安装软件,然而这个命令需要连外网下载软件,用maven下载jar包也需要外网.虚拟机在内网可以互相ping通,然而ping不了外网,于是通过试验,终于找到 ...

  8. Windows10 Enterprise版本周年更新问题

    安装Windows10的时候,蛋疼选择了企业版本,导致后来周年更新遇到了蛋疼的问题. 首先是无法接收到周年更新的推送.记得首个周年更新的时候,等了大半年都没有.后来使用了易升进行更新,可以检测到,但是 ...

  9. 恐怖的ifdown eth0;0

    下午闲的蛋疼,随手给测试机配了个浮动地址eth0:0. ping了下OK,内网访问没问题. 准备收手的时候,瞄了一眼ifcfg-eth0:0的配置,发现广播地址BROADCAST写成了BOADCAST ...

  10. java 数据库编程 学习笔记 不断更新

    最近开始学习java,感觉java的数据库编程需要发个随笔记录一下,话不多说 切入正题. 一.数据库访问技术的简介 应用程序  →  执行SQL语句 →数据库 → 检索数据结果 → 应用程序   ( ...