【题解】HNOI2008GT考试
这题好难啊……完全不懂矩阵加速递推的我TAT
这道题目要求我们求出不含不吉利数字的字符串总数,那么我们有dp方程 : dp[i][j](长度为 i 的字符串,最长与不吉利数字前缀相同的后缀长度为 j 的方案数)。 dp[i][j] = Σdp[i - 1][k] * a[k][j] (a 数组表示从 k 状态转移到 j 状态的方案数)。a 数组我们可以通过 kmp 对不吉利数字的每一个前缀后面加上‘0’~‘9’转移匹配得到(匹配成功表示成功转移状态,a[k][j]++;否则表示此时没有重合的后缀,a[k][0]++)。
此时这道题目我们已经拥有了一个相对优的解法了,但是还不够。注意到上面的式子,我们对于dp数组与a数组分别建立矩阵,dp矩阵是一个列矩阵,一列代表1~k的状态,a矩阵第 j 行上每个数分别表示a[j][k]。所以得到的答案dp[i][j]即为dp矩阵与a矩阵第 j 行的乘积。矩阵快速幂优化即可。
#include <bits/stdc++.h>
using namespace std;
#define maxn 100000
int n, m, Mod, k, ans;
char s[maxn], nxt[maxn]; int read()
{
int x = , k = ;
char c;
c = getchar();
while(c < '' || c > '') { if(c == '-') k = -; c = getchar(); }
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * k;
} struct Matrix
{
int num[][];
void init()
{
memset(num, , sizeof(num));
}
Matrix operator*(const Matrix &x)
{
Matrix tem;
tem.init();
for(int i = ; i < m; i ++)
for(int j = ; j < m; j ++)
for(int k = ; k < m; k ++)
{
tem.num[i][j] += (num[i][k] * x.num[k][j]) % Mod;
tem.num[i][j] %= Mod;
}
return tem;
}
}T, S; void KMP()
{
int j = ;
for(int i = ; i <= m; i ++)
{
while(j && s[j + ] != s[i]) j = nxt[j];
if(s[j + ] == s[i]) j ++;
nxt[i] = j;
}
j = ;
for(int i = ; i < m; i ++)
for(int k = ; k <= ; k ++)
{
j = i;
while(j && s[j + ] != (char) k + '') j = nxt[j];
if(s[j + ] == (char) k + '') T.num[i][j + ] ++;
else T.num[i][] ++;
}
} void Qpow()
{
for(int i = ; i < m; i ++) S.num[i][i] = ;
while(n)
{
if(n & ) S = S * T;
T = T * T;
n >>= ;
}
} int main()
{
n = read(), m = read(), k = read();
Mod = k;
scanf("%s", s + );
KMP();
Qpow();
for(int i = ; i < m; i ++)
ans = (ans + S.num[][i]) % Mod;
printf("%d\n", ans);
return ;
}
【题解】HNOI2008GT考试的更多相关文章
- 题解 GT考试
题目传送门 题目大意 给出\(n,m,k\),以及一个长度为\(m\)的数字串\(s_{1,2,...,m}\),求有多少个长度为\(n\)的数字串\(X\)满足\(s\)不出现在其中的个数模\(k\ ...
- HNOI2008GT考试
题目链接 考虑dp,f(i,j)表示做到了第i位(共n位),当前的后缀串与A1~Aj相匹配 接下来的方案数.转移的话枚举一个k=0~9表示这位选什么,如果选了以后,匹配的位置会改变到 j' ,j'可以 ...
- 竞赛题解 - NOIP2018 赛道修建
\(\mathcal {NOIP2018}\) 赛道修建 - 竞赛题解 额--考试的时候大概猜到正解,但是时间不够了,不敢写,就写了骗分QwQ 现在把坑填好了~ 题目 (Copy from 洛谷) 题 ...
- CSP-J 2020题解
CSP-J 2020题解 本次考试还是很有用的,至少把我浇了一盆冷水. 当使用民间数据自测的时候,我就自闭了. 估分是320,但有些比较低级的错误直接少掉80. 而且这套题应该上350才正常吧,也不是 ...
- jsoi2015 R2——滚粗记
考完感觉各种绝望溢出胸口,作为百度空间的最后一篇文章了吧 day 0 第二轮在南师附中……不能到外地玩了…… 其实在试机的时候就感觉不大对头,明明说好18:15试机结果拖到18:30…… 还有今年竟然 ...
- [SinGuLaRiTy] COCI 2016~2017 #5
[SinGuLaRiTy-1012] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved. 最近神犇喜欢考COCI...... 测试题目 对于所有的 ...
- 【BZOJ4738/UOJ#276】汽水(点分治,分数规划)
[BZOJ4738/UOJ#276]汽水(点分治,分数规划) 题面 BZOJ UOJ 题解 今天考试的题目,虽然说是写完了,但是感觉还是半懂不懂的来着. 代码基本照着\(Anson\)爷的码的,orz ...
- [Codeforces526F]Pudding Monsters 分治
F. Pudding Monsters time limit per test 2 seconds memory limit per test 256 megabytes In this proble ...
- 【BZOJ2423】最长公共子序列(动态规划)
[BZOJ2423]最长公共子序列(动态规划) 题面 BZOJ 洛谷 题解 今天考试的时候,神仙出题人\(fdf\)把这道题目作为一个二合一出了出来,我除了orz还是只会orz. 对于如何\(O(n^ ...
随机推荐
- js判断两个日期是否在几个月之内
//比较两个时间 time1,time2均为日期类型 //判断两个时间段是否相差 m 个月 function completeDate(time1 , time2 , m) { var diffyea ...
- 【redis常用的键值操作及性能优化】
服务端 启动redis服务 { // -a:指定密码 -h:指定主机 -p:指定端口 } //让redis 服务中断崩溃 //保存和关闭 //后台备份 //设置登录密码 //redis-benchma ...
- vue服务端渲染添加缓存
缓存 虽然 Vue 的服务器端渲染(SSR)相当快速,但是由于创建组件实例和虚拟 DOM 节点的开销,无法与纯基于字符串拼接(pure string-based)的模板的性能相当.在 SSR 性能至关 ...
- Spring笔记2
Bean生命周期 1 实例化 2 注入属性 3 BeanNameAware 4 BeanFactoryAware 5 ApplicationContextAware 6 BeanPostProcess ...
- 使用webBrowser进行C#和JS通讯
.前台调用后台: 在webBrowser使用过程中为了C#和js通讯,webBrowser必须设置ObjectForScripting的属性,它是一个object,这个object可以提供给webBr ...
- Hadoop(6)-HDFS的shell操作
1.基本语法 使用 hadoop fs 具体命令 或者 hdfs dfs 具体命令 hadoop命令的shell源码 hdfs命令的shell源码 由此可见,这两个命令最后都是执行的一个jav ...
- Idea 2017 激活方法
http://www.cnblogs.com/suiyueqiannian/p/6754091.html
- P1396 营救(最小瓶颈路)
题目描述 “咚咚咚……”“查水表!”原来是查水表来了,现在哪里找这么热心上门的查表员啊!小明感动的热泪盈眶,开起了门…… 妈妈下班回家,街坊邻居说小明被一群陌生人强行押上了警车!妈妈丰富的经验告诉她小 ...
- JAVA多进程入门
概念 并行和并发 并行:物理上的实现,在同一时间点上发生 并发:两个事件在一个时间段内发生,如单片机的单核多线程 进程和线程 进程:一个应用程序可以有多个进程,每一个进程有一个独立的内存空间 线程:一 ...
- Django调试models输出的SQL语句
django1.3在shell下,调试models变得更为简单了,不用像之前的版本,手工去调用django query,才能打印出之前的代码是执行的什么SQL语句. 1.3开始只需在settings. ...