CF1400F - x-prime Substrings
首先发现 \(x\) 很小,所以发现对应的 x-prime 字符串数也很少,最多的情况是 \(x = 19\),有 2399 个,先爆搜出来。
现在问题变成了,删去最少的字符,使字符串内没有这些模式串。
那么建 AC 自动机,把模式串终点标记,即在非终点行走,每次可以跳过字符,求跳过的最小值。
DP 一下,设 \(f_{i, u}\) 为前 \(i\) 个字符,当前在 AC 自动机上的 \(u\) 号节点,其中没有 x-prime 子串,删除字符的最小值。
- 有边 \((u, v)\),即从 \(u\) 走 \(s[i + 1]\) 字符到 \(v\),若 \(v\) 点合法,即 \(f_{i + 1, v} = f_{i, u}\)
- 也可以不走,原地不动,\(f_{i + 1, u} = f_{i, u} + 1\)
滚动数组可以滚掉第一维,这样空间就够了。最坏 \(x = 19\) 时 AC 自动机有 5000 左右的点数。
最坏复杂度 \(5000 \times 1000 = 5\times 10^6\)。跑得过。
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
typedef long long LL;
const int N = 2005, S = 5005, INF = 0x3f3f3f3f;
int n, x, d[N], cnt, tr[S][9], fail[S];
int idx, f[S], g[S], q[S];
bool match[S];
char s[N];
bool inline check(int m) {
for (int i = 1; i <= m; i++) {
int s = 0;
for (int j = i; j <= m; j++) {
s += d[j];
if (s != x && x % s == 0) return false;
}
}
return true;
}
void inline insert(int m) {
int p = 0;
for (int i = 1; i <= m; i++) {
int ch = d[i] - 1;
if (!tr[p][ch]) tr[p][ch] = ++idx;
p = tr[p][ch];
}
match[p] = true;
}
void dfs(int u, int rest) {
if (!rest) {
if (check(u - 1)) insert(u - 1);
return;
}
for (int i = 1; i <= min(rest, 9); i++) {
d[u] = i;
dfs(u + 1, rest - i);
}
}
void inline build() {
int hh = 0, tt = -1;
for (int i = 0; i < 9; i++)
if (tr[0][i]) q[++tt] = tr[0][i];
while (hh <= tt) {
int u = q[hh++];
for (int i = 0; i < 9; i++) {
int &v = tr[u][i];
if (!v) v = tr[fail[u]][i];
else fail[v] = tr[fail[u]][i], q[++tt] = v;
}
}
}
int main() {
scanf("%s%d", s + 1, &x);
n = strlen(s + 1);
dfs(1, x);
build();
memset(f, 0x3f, sizeof f); f[0] = 0;
for (int i = 1; i <= n; i++) {
int ch = s[i] - '1';
for (int j = 0; j <= idx; j++) g[j] = f[j], f[j] = INF;
for (int j = 0; j <= idx; j++) {
if (g[j] != INF) {
f[j] = min(f[j], g[j] + 1);
int v = tr[j][ch];
if (!match[v]) f[v] = min(f[v], g[j]);
}
}
}
int ans = 2e9;
for (int i = 0; i <= idx; i++) ans = min(ans, f[i]);
printf("%d\n", ans);
return 0;
}
CF1400F - x-prime Substrings的更多相关文章
- Java 素数 prime numbers-LeetCode 204
Description: Count the number of prime numbers less than a non-negative number, n click to show more ...
- Prime Generator
Peter wants to generate some prime numbers for his cryptosystem. Help him! Your task is to generate ...
- POJ 2739. Sum of Consecutive Prime Numbers
Sum of Consecutive Prime Numbers Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 20050 ...
- [LeetCode] Unique Substrings in Wraparound String 封装字符串中的独特子字符串
Consider the string s to be the infinite wraparound string of "abcdefghijklmnopqrstuvwxyz" ...
- UVa 524 Prime Ring Problem(回溯法)
传送门 Description A ring is composed of n (even number) circles as shown in diagram. Put natural numbe ...
- Sicily 1444: Prime Path(BFS)
题意为给出两个四位素数A.B,每次只能对A的某一位数字进行修改,使它成为另一个四位的素数,问最少经过多少操作,能使A变到B.可以直接进行BFS搜索 #include<bits/stdc++.h& ...
- hdu 5901 count prime & code vs 3223 素数密度
hdu5901题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5901 code vs 3223题目链接:http://codevs.cn/problem ...
- 最小生成树 prime zoj1586
题意:在n个星球,每2个星球之间的联通需要依靠一个网络适配器,每个星球喜欢的网络适配器的价钱不同,先给你一个n,然后n个数,代表第i个星球喜爱的网络适配器的价钱,然后给出一个矩阵M[i][j]代表第i ...
- 最小生成树 prime poj1258
题意:给你一个矩阵M[i][j]表示i到j的距离 求最小生成树 思路:裸最小生成树 prime就可以了 最小生成树专题 AC代码: #include "iostream" #inc ...
随机推荐
- fork-vfork -exit&_exit
昨天帮人查bug,发现了一个vfork fork exit _exit不分导致的问题. 使用vfork 后调用exit导致的问题. 主要需要弄清楚他们之间的区别: 1. fork ():子进程拷 ...
- IO复用之poll
主要用一个例程来讲解poll,包含客户端和服务器端. poll函数没有FD_SETSIZE的限制 int poll(struct pollfd * fdarray, unsigned long nfd ...
- shell编程之算术扩展(引号、命令替换、算术扩展)
1.单引号 .双引号.反引号的区别 单引号:忽略所有特殊字符 双引号:忽略大部分特殊字符($ `等字符除外) [root@tlinux shell]# echo '*' * [root@tlinux ...
- struts2中数据的传输
1.传统的写多个request接受参数方法. 2.struts2中的多个setter方法,getter方法 3.利用实体bean,让strut2 实例bean,少写setter方法,getter方法, ...
- 利用移动硬盘安装windows7系统
首先把win7系统镜像的iso文件解压到移动硬盘中 将移动硬盘设置为活动分区 设置活动分区的方法 Diskpart程序实现U盘安装WIN7的方法: 将Win7安装盘中的所有文件拷贝到硬盘文件夹中,我们 ...
- NUC972当检测到sd卡时,在sd卡驱动中操作gpio开启sd卡的电源,解决sd卡因低电压有时识别不正常的问题
1.根据硬件原理图,找到对应控制sd卡电源的gpio引脚,并在sd卡驱动文件中定义操作改该引脚的宏 2.在sd卡检测函数中,使用glib增加开sd卡电源的操作,如此当sd卡每次被检测到时,驱动中就会自 ...
- 基于tcp的socket通信
# socket # socekt是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,socket其实就是一个门面模式,它 # 把复杂的tcp/ip协议族隐藏在socket接 ...
- 使用phpExcel读取excel文件
include_once '../include/common.inc.php'; include_once MC_ROOT.'include/smarty.inc.php'; date_defaul ...
- 数据丢失如何恢复?EasyRecovery帮你快速实现
在日常使用电脑时,我们经常会遇到误删文件的情况,若文件还未被彻底删除,我们还可以通过电脑中的回收站将其恢复,但若是回收站都被清空的话,想要恢复文件就变得比较困难了,而EasyRecovery可以很好的 ...
- 紧急发布用cherry-pick检出当前分支所有我的提交记录
目录 背景 操作命令 cherry-pick git log Shell脚本 背景 公司接了个新项目,需在平台上增加几个新接口,问题是本来说是和平台一起迭代发布的时间提前了,但当前的代码都和其他开发人 ...