题目链接 先考虑 假设S确定,使构造S操作次数最小的方案应是:对T建SAM,S在SAM上匹配,如果有S的转移就转移,否则操作数++,回到根节点继续匹配S.即每次操作一定是一次极大匹配. 简单证明:假设S="ABCD",T有子串"A","AB","CD","BCD",那么步数最小方案是选"AB"再接上"CD",而不是提前断开选择"A"+"B…
Description SD有一名神犇叫做Oxer,他觉得字符串的题目都太水了,于是便出了一道题来虐蒟蒻yts1999.   他给出了一个字符串T,字符串T中有且仅有4种字符 'A', 'B', 'C', 'D'.现在他要求蒟蒻yts1999构造一个新的字符串S,构造的方法是:进行多次操作,每一次操作选择T的一个子串,将其加入S的末尾.   对于一个可构造出的字符串S,可能有多种构造方案,Oxer定义构造字符串S所需的操作次数为所有构造方案中操作次数的最小值.   Oxer想知道对于给定的正整数…
4180: 字符串计数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 164  Solved: 75 Description SD有一名神犇叫做Oxer,他觉得字符串的题目都太水了,于是便出了一道题来虐蒟蒻yts1999. 他给出了一个字符串T,字符串T中有且仅有4种字符 'A', 'B', 'C', 'D'.现在他要求蒟蒻yts1999构造一个新的字符串S,构造的方法是:进行多次操作,每一次操作选择T的一个子串,将其加入S的末尾. 对于一个可构…
[题意]给定n个禁忌字符串和字符集大小alphabet,保证所有字符在集合内.一个字符串的禁忌伤害定义为分割能匹配到最多的禁忌字符串数量(一个可以匹配多次),求由字符集构成的长度为Len的字符串的期望禁忌伤害.n<=5,1<=alphabet<=26,len<=10^9. [算法]AC自动机+期望+矩阵快速幂 [题解]参考:BZOJ2553: [BeiJing2011]禁忌 首先对于一个确定的字符串,每个匹配的禁忌字符串视为一条线段,就是经典的不重叠最大线段数问题. 通用的贪心做法…
[题意]给定n个原串和m个禁忌串,要求用原串集合能拼出的不含禁忌串且长度为L的串的数量.(60%)n,m<=50,L<=100.(40%)原串长度为1或2,L<=10^18. [算法]AC自动机+DP+矩阵快速幂 [题解]其实题意的数据范围不太清晰,反正开200个点就足够了. 因为要匹配禁忌串,所以对禁忌串集合建立AC自动机,标记禁忌串结尾节点,以及下传到所有能fail到的点(这些点访问到都相当于匹配了禁忌串). 令f[i][j]表示匹配到节点i,长度为j的串的数量,先预处理a[i][j…
Luogu-3250 [BJOI2017]魔法咒语(AC自动机,矩阵快速幂) 题目链接 题解: 多串匹配问题,很容易想到是AC自动机 先构建忌讳词语的AC自动机,构建时顺便记录一下这个点以及它的所有后缀有没有忌讳词语,即对于每个AC自动机上的结点\(x\),\(p[x].p|=p[p[x].f].p\) 然后前半部分分和后半是两道完全不同的题目(滑稽 前60分: 这些部分分的特征是\(L\le 100\) 直接AC自动机上\(dp\)就好了,枚举匹配长度\(i\),当前匹配到的点\(x\),以及…
[BZOJ1494][NOI2007]生成树计数(动态规划,矩阵快速幂) 题面 Description 最近,小栋在无向连通图的生成树个数计算方面有了惊人的进展,他发现: ·n个结点的环的生成树个数为n. ·n个结点的完全图的生成树个数为n^(n-2).这两个发现让小栋欣喜若狂,由此更加坚定了他继续计算生成树个数的 想法,他要计算出各种各样图的生成树数目.一天,小栋和同学聚会,大家围坐在一张大圆桌周围.小栋看了看, 马上想到了生成树问题.如果把每个同学看成一个结点,邻座(结点间距离为1)的同学间…
4180: 字符串计数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 146  Solved: 66[Submit][Status][Discuss] Description SD有一名神犇叫做Oxer,他觉得字符串的题目都太水了,于是便出了一道题来虐蒟蒻yts1999.   他给出了一个字符串T,字符串T中有且仅有4种字符 'A', 'B', 'C', 'D'.现在他要求蒟蒻yts1999构造一个新的字符串S,构造的方法是:进行多次操作,每一次…
Description SD有一名神犇叫做Oxer,他觉得字符串的题目都太水了,于是便出了一道题来虐蒟蒻yts1999. 他给出了一个字符串T,字符串T中有且仅有4种字符 'A', 'B', 'C', 'D'.现在他要求蒟蒻yts1999构造一个新的字符串S,构造的方法是:进行多次操作,每一次操作选择T的一个子串,将其加入S的末尾. 对于一个可构造出的字符串S,可能有多种构造方案,Oxer定义构造字符串S所需的操作次数为所有构造方案中操作次数的最小值. Oxer想知道对于给定的正整数N和字符串T…
考虑对一个串如何分割能取得最大值.那么这是一个经典的线段覆盖问题,显然每次取右端点尽量靠前的串.于是可以把串放在AC自动机上跑,找到一个合法串后就记录并跳到根. 然后考虑dp.设f[i][j]表示前i位走到AC自动机上j节点的概率,枚举下个字符即可转移.同时记录此时期望伤害,找到合法串就统计入答案. 并且注意到每次转移是相同的.矩阵快速幂优化即可. 以及非常卡精度,需要全程long double.cout的保留小数位数误差是相当大的,必须用printf.并且转移到某个字符的概率即1/alphab…
注意到每个路线相邻车站的距离不超过K,也就是说我们可以对连续K个车站的状态进行状压. 然后状压DP一下,用矩阵快速幂加速运算即可. #include <stdio.h> #include <stdlib.h> #include <string.h> #include <algorithm> #define MAXN 140 #define MOD 30031 using namespace std; struct Matrix { int num[MAXN]…
[题意]给定n个点m边的无向图,求A到B恰好经过t条边的路径数,路径须满足每条边都和前一条边不同.n<=20,m<=60,t<=2^30. [算法]矩阵快速幂 [题解]将图的邻接矩阵进行矩阵快速幂就可以得到恰好经过t条边的路径数,但不能满足题目要求. 改为对原图的边进行相互连边,将经过同一个点的边两两连边,这样就是新邻接矩阵的t-1步. 为了满足题目要求,当两条边互为反向边时不连边即可. 最后乘上从A出发的边的矩阵,然后统计到达B的路径数. 复杂度O((m*2)^3 log t). #i…
接上一篇,那个递推式显然可以用矩阵快速幂优化...自己随便YY了下就出来了,学了一下怎么用LaTeX画公式,LaTeX真是个好东西!嘿嘿嘿 如上图.(刚画错了一发...已更新 然后就可以过V2了 orz CZL卡常大师,我怎么越卡越慢啊QAQ #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> #define ll long…
注意到周期234的lcm只有12,也就是以12为周期,可以走的状态是一样的 所以先预处理出这12个状态的转移矩阵,乘起来,然后矩阵快速幂优化转移k/12次,然后剩下的次数暴力转移即可 #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int mod=10000; int n,m,s,t,k,x,y,nf,T,w[60]; struct jz { int a[6…
矩阵乘法一般不满足交换律!!所以快速幂里需要注意乘的顺序!! 其实不难,设f[i]为i的答案,那么f[i]=(f[i-1]w[i]+i)%mod,w[i]是1e(i的位数),这个很容易写成矩阵的形式,然后按每一位分别矩阵快速幂即可 矩阵: f[i-1] w[i] 1 1 f[i] i-1 0 1 1 = i 1 0 0 1 1 #include<iostream> #include<cstdio> using namespace std; long long n,mod,t; lo…
第一道矩阵快速幂的题:模板题: #include<stack> #include<queue> #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define INF 0x3f3f3f3f typedef long long ll; ; int n;…
题目:https://ac.nowcoder.com/acm/contest/885/B 题意:给你x0,x1,让你求出xn,递推式时xn=a*xn-1+b*xn-2 思路:这个n特别大,我自己没有摸清欧拉降幂的性质,瞎套了,然后其实因为底数是一个矩阵,并不能运用这一定理,但是这个n又这么大,我们就可以使用倍增 这里用2倍增有点麻烦,我们就直接用10倍增,然后这个递推式很明显就能看出是一个2*2的矩阵快速幂,然后求解即可 #include<bits/stdc++.h> #define maxn…
3473: 字符串 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 354  Solved: 160[Submit][Status][Discuss] Description 给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串? Input 第一行两个整数n,k. 接下来n行每行一个字符串. Output 一行n个整数,第i个整数表示第i个字符串的答案. 字符串总长度L n,k,L<=1e5 研究了两节多课…
建一个广义后缀自动机(每加完一个串都返回root),在parent树上dpsum记录合法长度,打着时间戳往上跳,最后每个串在自动机上跑一变统计答案即可. 后缀数组理解起来可能方便一点,但是难写,就只说一下思路--把这些串加上特殊字符拼起来,然后按着sa扫,对每个位置二分长度,再左右端点(用height判断是否有k个) #include<iostream> #include<cstdio> #include<cstring> using namespace std; co…
状压dp, 然后转移都是一样的, 矩阵乘法+快速幂就行啦. O(logN*2^(3m)) --------------------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm>   using namespace std;   #define b(x) (1 &l…
把双向边拆成2条单向边, 用边来转移...然后矩阵乘法+快速幂优化 --------------------------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm>   using namespace std;   const int MOD = 45989; const…
题目 真是一道好题 首先根据一个非常显然的贪心,如果给出了一个串\(S\),我们如何算最小操作次数呢 非常简单,我们直接把\(S\)拉到\(T\)的\(SAM\)上去跑,如果跑不动了就停下来,重新回到\(1\)继续跑 于是我们建出一个\(SAM\)之后可以写一个这样的暴力,设\(d[i][j][k]\)表示从\(i\)点到\(j\)点走\(i\)条边的最长路,对于那些走不动的边,我们可以接到\(1\)号节点对应的出边上去,边权为\(1\),其余的边权为\(0\),矩阵优化一下就是\(O(|T|^…
标签那么长是因为做法太多了... 题目链接: (bzoj 3277) https://www.lydsy.com/JudgeOnline/problem.php?id=3277 (bzoj 3473) https://www.lydsy.com/JudgeOnline/problem.php?id=3473 题解: 先讲三个做法公共部分: 建出广义SAM,然后对于每个点求出它在多少字符串中出现过. 做法一 把每个字符串在广义SAM上暴力跑.每跑到一个点就暴力沿着fail树往上跳,标记跳过的点,直…
题目大意: 给你一堆模式串和文本串 对于每个文本串,我们可以把它不可重叠地拆分成很多子串,如果拆分出的串作为子串出现在了任何一个模式串中,我们称它是“眼熟的”,我们必须保证“眼熟的”子串总长度不小于文本串的90%,现在定义一个数$L$,表示拆分出的子串的最小长度,求每个文本串的$L$的最大值 神题 考虑$L$的性质,发现$L$越大,“眼熟的子串”总长度越长 可以这样简单证明,长度越小的串,对于匹配越有利,因为如果一个大串出现在了模式串中,那么它的所有子串一定出现在了模式串中,反之,小串出现在模式…
这题就比较有趣了. 首先匹配一遍,然后统计子树叶子节点中包含大于等于k的节点个数(HH的项链) 然后就可以搞了. 关于合法的情况数,显然是l[i]-l[fa[i]],然后向下下传即可(YY一下). #include <vector> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define F…
题意:给一些字符串的集合S和整数n,求满足 长度为n 只含charset = {'A'.'T‘.'G'.'C'}包含的字符 不包含S中任一字符串 的字符串的种类数. 思路:首先对S建立ac自动机,考虑向ac自动机中的每种状态后加charset中的字符,如果终态不为“接受状态”,也就是不与S中的任一字符串匹配,则将这次转移记为有效,方法数加1.这样可以建立状态之间的转移矩阵D,表示由一个状态接受1个字符后的方案数,D自乘n次,就得到了任一状态接受n个字符形成的不同字符串种类数,其中从“0”到“i”…
题目链接 设f[i][j]为当前是第i位考号.现在匹配到第j位(已有j-1位和A[]匹配)的方案数 因为假如当前匹配j位,如果选择的下一位与A[j+1]不同,那么新的匹配位数是fail[j]而不是0,那么设由匹配j位转移到匹配k位的方案数为t[j][k] 那么 \(f[i][j] = ∑f[i-1][k]*t[k][j]\) 这个式子是线性的,于是可以先计算出t矩阵的n次幂,最后乘以初始矩阵 t矩阵枚举当前匹配多少位后,枚举下次选择的数即可,利用KMP计算现在匹配的位数 //824kb 24ms…
http://poj.org/problem?id=3233 Matrix Power Series Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 18658   Accepted: 7895 Description Given a n × n matrix A and a positive integer k, find the sum S = A + A2 + A3 + … + Ak. Input The inpu…
http://www.lydsy.com/JudgeOnline/problem.php?id=3231   和斐波那契一个道理在最后加一个求和即可 #include<cstdio> #include<cstring> #include<iostream> //using namespace std; ; ; long long modn; long long n,l,r; ]={}; struct mat{ ][]; mat(){ memset(e,,sizeof(e…
题目给m个病毒串,问不包含病毒串的长度n的DNA片段有几个. 感觉这题好神,看了好久的题解. 所有病毒串构造一个AC自动机,这个AC自动机可以看作一张有向图,图上的每个顶点就是Trie树上的结点,每个结点都可以看作是某个病毒串的前缀,Trie树的根则是空字符串. 而从根出发,在AC自动机上跑,经过k次转移到达某个结点,这个结点所代表的病毒串前缀可以看作长度为k的字符串的后缀,如果接下去跑往ATCG四个方向转移,就能到达新的结点,转移到新的长k+1字符串的后缀. 这样带着一个后缀状态的转移就能绕开…