题意:给你一个字符串,有2种消除方式:1:消除一个单独的字母,代价为a.2:s[j]到s[k]是s[1]到s[j - 1]的子串,那么s[j]到s[k]可以消除,代价为b,问最小的代价. 思路:官方题解说的很明白了. 代码: #include <bits/stdc++.h> #define LL long long #define INF 0x3f3f3f3f using namespace std; const int maxn = 5010; int dp[maxn]; int v[max…
题目链接: https://codeforces.com/contest/1120/problem/C 题意: 从前往后压缩一段字符串 有两种操作: 1.对于单个字符,压缩它花费$a$ 2.对于末尾一段字符串,如果这段字符串是已经压缩过字符串的子串,那么可以选择压缩它,花费为$b$ 数据范围: $1\leq |S| \leq 5000$ $1\leq a \leq 5000$ $1\leq b \leq 5000$ 分析: 这道题目我们需要解决一个问题,计算某个子串出现的最早位置 转移,如果这个…
[Hihocoder1413]Rikka with String(后缀自动机) 题面 Hihocoder 给定一个小写字母串,回答分别把每个位置上的字符替换为'#'后的本质不同的子串数. 题解 首先横跨'#'左右的串一定恰好只会出现一次,所以直接统计答案. 那么剩下的部分就是左右的本质不同的子串数. 我们把答案拆成三个部分,先是左侧本质不同子串的个数,再是右侧本质不同子串的个数.最后再减去既在左侧出现过,又在右侧出现过的串的个数. 左右两个直接用\(SAM\)算就好了. 在两侧同时出现过的,我们…
[题目]A. A String Game [题意]给定目标串S和n个子串Ti,Alice和Bob轮流选择一个子串操作,必须且只能在子串末尾添加一个字符使得新串也是S的子串,不能操作即输,求胜利者.|S|<=10^5,n<=100.多组数据,保证Σ|S|<=3*10^7. [算法]后缀自动机+博弈论SG函数 [题解]对S建SAM,每次子串操作相当于沿SAM的实边走,所以可以对SAM进行DAG上的sg函数计算,最后多个子串的sg值的异或和就是答案,非0先手必胜. #include<cs…
传送门 题意: 给出\(p,q\),现在要你生成一个字符串\(s\). 你可以进行两种操作:一种是花费\(p\)的代价随意在后面添加一个字符,另一种是花费\(q\)的代价可以随意赋值前面的一个子串. 现在问最小代价是多少. 思路: 考虑\(dp\),那么就有转移方程:\(dp[i]=min\{dp[i-1]+p,dp[j]+q\}\),即直接对两种操作取min即可. 注意到该\(dp\)方程有一个性质:其值肯定为单调不降的.因为如果有\(dp[i-1]>dp[i]\),那此时我们跟着复制过来肯定…
传送门 解题思路 肯定先要建出来广义后缀自动机.刚开始以为是个二分+贪心,写了一下结果\(20\)分.说一下正解,首先显然\(L_0\)具有单调性,是可以二分的.考虑二分后怎样判合法,对于分割序列很容易想到\(dp\),设\(f_i\)表示前\(i\)个字符匹配成功数量,那么有转移方程\(f_i=max(f_j+i-j)(i-j>=L\) 且 \(j\)到\(i\)可以匹配 \()\),\(L\)是二分出来的限制,判断是否能匹配可以预处理,预处理出\(mth_i\)表示\(i\)最多能与往前\(…
题意: 有个打字机,在当前字符串后新加一个字花费p,把当前字符串的一个连续子串拷贝到当前字符串的末尾花费q,给定一个字符串,求用打字机打出这个字符串的最小花费. 题解: 容易想到用dp 记dp[i]为打出前i个字符的最小花费,对于每个i,令 A=dp[i-1]+p B=dp[j]+q 其中j为最小的,使得s[j+1~i]是s[1~j]的连续子串的值 其实就是,把这个字符串咔嚓切一刀,看后面的部分是不是前面部分的子串,如果不是,就把切的地方向后挪,前面的部分是原串,后面的部分是模式串. dp[i]…
传送门 解题思路: 首先在后缀树上,确定了一个节点就相当于确定了一个串,那么一个点对应的串在另外一个点对应的串产生贡献,当且仅当这个点在当前点子树内. 那么考虑一个新的点在串中对串答案的贡献在一条树链上或者反过来说,就是产生贡献的点在这个点子树内. 才知道自己写的广义后缀自动机板子是错的QAQ 考虑n非常小,贡献可以单独算,再配合BZOJ2555的启发,这道题就可以使用LCT轻松地解决了. 代码: #include<cstdio> #include<cstring> #includ…
题意: 给一个1e5的串str,然后有三个起始空串,不超过1000次操作,对三个字符串的一个尾部加一个字符或者减一个字符,保证每个字符不会超过250 每次操作之后询问你这三个串是不是可以组成str的子序列, 比如ab,cd,ef可以组成acgbdef的子序列 思路: dp[i][j][k]为三个串分别匹配到i,j,k的时候组成的子序列的最后一个字符在str中的位置,如果dp[strlen(str1)][strlen(str2)][strlen(str3)]>n则输出no 对每一次询问我们可以处理…
题目链接 1.求A的最短子串,它不是B的子串. 子串是连续的,对B建SAM,枚举起点,在SAM上找到第一个无法匹配点即可.O(n)用SAM能做吗..开始想错了. 2.求A的最短子串,它不是B的子序列. 子序列...直接建SAM没啥用.考虑A[i]和上一位A[i-1],用f[i][j]表示到A[i]匹配到B[j]时连续的A的子串长度,如果A[i]==B[j],则f[i][j]=max{f[i-1][k]+1}(k<j). 是取max啊,因为B会尽可能匹配.枚举完B[n]后且max{f[i][k]}…