1400F - 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的更多相关文章

  1. Java 素数 prime numbers-LeetCode 204

    Description: Count the number of prime numbers less than a non-negative number, n click to show more ...

  2. Prime Generator

    Peter wants to generate some prime numbers for his cryptosystem. Help him! Your task is to generate ...

  3. POJ 2739. Sum of Consecutive Prime Numbers

    Sum of Consecutive Prime Numbers Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 20050 ...

  4. [LeetCode] Unique Substrings in Wraparound String 封装字符串中的独特子字符串

    Consider the string s to be the infinite wraparound string of "abcdefghijklmnopqrstuvwxyz" ...

  5. UVa 524 Prime Ring Problem(回溯法)

    传送门 Description A ring is composed of n (even number) circles as shown in diagram. Put natural numbe ...

  6. Sicily 1444: Prime Path(BFS)

    题意为给出两个四位素数A.B,每次只能对A的某一位数字进行修改,使它成为另一个四位的素数,问最少经过多少操作,能使A变到B.可以直接进行BFS搜索 #include<bits/stdc++.h& ...

  7. hdu 5901 count prime & code vs 3223 素数密度

    hdu5901题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5901 code vs 3223题目链接:http://codevs.cn/problem ...

  8. 最小生成树 prime zoj1586

    题意:在n个星球,每2个星球之间的联通需要依靠一个网络适配器,每个星球喜欢的网络适配器的价钱不同,先给你一个n,然后n个数,代表第i个星球喜爱的网络适配器的价钱,然后给出一个矩阵M[i][j]代表第i ...

  9. 最小生成树 prime poj1258

    题意:给你一个矩阵M[i][j]表示i到j的距离 求最小生成树 思路:裸最小生成树 prime就可以了 最小生成树专题 AC代码: #include "iostream" #inc ...

随机推荐

  1. read/write系统调用

    /*拷贝文件内容实例read系统调用.write系统调用ssize_t read(int fd, void *buf, size_t count);ssize_t write(int fd, cons ...

  2. linux开机启动及运行级别、root密码丢失、单用户模式只读的处理方法

    linux系统启动大致步骤如下:  加电自检-->根据BIOS中的设置从指定的设备启动-->找到设备MBR中的bootloader引导启动系统-->启动kernel-->启动i ...

  3. arm-linux校时和时钟同步

    # 将时间写到系统 date 2020.08.25-14:02:00 # 将时间同步到硬件时钟芯片 hwclock -f /dev/rtc1 -w # 将时间从硬件时钟芯片同步到系统 hwclock ...

  4. 算法题目:北邮python 3-C 排队前进

    一道python作业的题目,比较有意思,题目如下: 题目描述 有 n 个人排队向一个方向前进,他们前进的速度并不一定相同. 最开始即 t=0 时,每个人的位置并不相同.可以把他们放在数轴上,设他们前进 ...

  5. 微信公众号平台Url Token EncodingAESKey 注意点

    最近公司让我开发微信公众号平台扫码登录,同步用户信息于PC端,所做的过程当中遇到了一些坑,做完了就总结一下需要注意的点,如若大家开发过程中遇到同样的问题,可以借鉴! 第一:配置域名 作用:配置域名为了 ...

  6. powertool

    powertool简介 PowerTool 一款免费强大的进程管理器,支持进程强制结束,可以Unlock占用文件的进程,查看文件/文件夹被占用的情况,内核模块和驱动的查看和管理,进程模块的内存的dum ...

  7. 安恒DASCTF 四月战 WP

    web1 打开提就是源码审计 考点:反序列化POP链.反序列化字符串逃逸 show_source("index.php"); function write($data) { ret ...

  8. js替换div里的内容

    <!DOCTYPE html><html><head><meta charset="utf-8"><title>< ...

  9. FL Studio带你走进混音的世界

    混音,是把多种音源整合到一个立体音轨或单音音轨中,通俗讲就是对多种声音进行调整后叠加在一起,这样可以让音乐听起来非常有层次感,尤其是在电音制作过程中,混音的质量更是起到了决定性的作用.音乐制作软件FL ...

  10. JUC并发工具包之Semaphore

    目录 Semaphore (JDK) Timed Semaphore (Apache Commons) Semaphore vs. Mutex CodeRepo Semaphore (JDK) 我们使 ...