大意: 给定串$s,t$, 给定整数$x$, 求判断$t$是否能划分为至多$x$段, 使这些段在$s$中按顺序,不交叉的出现.

设$dp_{i,j}$表示$s$匹配到$i$位, 划分了$j$段, 匹配到$t$中的最大位置

每次取一个极长的lcp转移即可, lcp可以二分哈希或者用后缀数组+RMQ求

#include <iostream>
#include <sstream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <cstring>
#include <bitset>
#include <functional>
#include <random>
#define REP(i,a,n) for(int i=a;i<=n;++i)
#define PER(i,a,n) for(int i=n;i>=a;--i)
#define hr putchar(10)
#define pb push_back
#define lc (o<<1)
#define rc (lc|1)
#define mid ((l+r)>>1)
#define ls lc,l,mid
#define rs rc,mid+1,r
#define x first
#define y second
#define io std::ios::sync_with_stdio(false)
#define endl '\n'
#define DB(a) ({REP(__i,1,n) cout<<a[__i]<<',';hr;})
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int P = 1e9+7, INF = 0x3f3f3f3f;
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
ll qpow(ll a,ll n) {ll r=1%P;for (a%=P;n;a=a*a%P,n>>=1)if(n&1)r=r*a%P;return r;}
ll inv(ll x){return x<=1?1:inv(P%x)*(P-P/x)%P;}
inline int rd() {int x=0;char p=getchar();while(p<'0'||p>'9')p=getchar();while(p>='0'&&p<='9')x=x*10+p-'0',p=getchar();return x;}
//head const int N = 1e6+50;
int n,m,x;
char s[N],t[N];
int dp[N][40];
void chkmax(int &a, int b) {a<b?a=b:0;} int Log[N],f[20][N];
void init(int a[N],int n) {
Log[0] = -1;
REP(i,1,n) f[0][i] = a[i], Log[i]=Log[i>>1]+1;
REP(j,1,19) for (int i=0;i+(1<<j-1)-1<=n; ++i) {
f[j][i] = min(f[j-1][i],f[j-1][i+(1<<j-1)]);
}
}
int RMQ(int l, int r) {
int t = Log[r-l+1];
return min(f[t][l],f[t][r-(1<<t)+1]);
} int c[N],rk[N],h[N],sa[N];
void build(int *a, int n, int m) {
a[n+1] = rk[n+1] = h[n+1] = 0;
int i,*x=rk,*y=h;
for(i=1;i<=m;i++) c[i]=0;
for(i=1;i<=n;i++) c[x[i]=a[i]]++;
for(i=1;i<=m;i++) c[i]+=c[i-1];
for(i=n;i;i--) sa[c[x[i]]--]=i;
for(int k=1,p;k<=n;k<<=1) {
p=0;
for(i=n-k+1;i<=n;i++) y[++p]=i;
for(i=1;i<=n;i++) if(sa[i]>k) y[++p]=sa[i]-k;
for(i=1;i<=m;i++) c[i]=0;
for(i=1;i<=n;i++) c[x[y[i]]]++;
for(i=1;i<=m;i++) c[i]+=c[i-1];
for(i=n;i;i--) sa[c[x[y[i]]]--]=y[i];
swap(x,y); x[sa[1]]=1; p=1;
for(i=2;i<=n;i++)
x[sa[i]]=(y[sa[i-1]]==y[sa[i]] && y[sa[i-1]+k]==y[sa[i]+k])?p:++p;
if(p==n) break; m=p;
}
for(i=1;i<=n;i++) rk[sa[i]]=i;
for(int i=1,j,k=0;i<=n;i++) {
if(k) k--;
j=sa[rk[i]-1];
while(a[i+k]==a[j+k]) k++;
h[rk[i]] = k;
}
} int lcp(int x, int y) {
x = rk[x], y = rk[y];
if (x>y) swap(x,y);
return RMQ(x+1,y);
} int a[N];
int main() {
scanf("%d%s%d%s%d",&n,s+1,&m,t+1,&x);
REP(i,1,n) a[i]=s[i]-'a'+1;
a[n+1]=30;
REP(i,n+2,n+m+1) a[i]=t[i-n-1]-'a'+1;
build(a,n+m+1,100);
init(h,n+m+1);
//dp[i][j] = s的前i位,t中分j段的最长匹配位置
//dp[i][j] <- dp[i-1][j]
//dp[i+lcp(i,dp[i-1][j]+1)-1][j+1] <- dp[i-1][j]
REP(i,1,n) REP(j,0,x) {
int &r = dp[i-1][j];
chkmax(dp[i][j],r);
if (r!=m) {
int t = lcp(i,n+r+2);
chkmax(dp[i+t-1][j+1],r+t);
}
}
REP(i,0,x) if (dp[n][i]==m) return puts("YES"),0;
puts("NO");
}

Liar CodeForces - 822E (dp,后缀数组)的更多相关文章

  1. CodeForces - 113B Petr# (后缀数组)

    应该算是远古时期的一道题了吧,不过感觉挺经典的. 题意是给出三一个字符串s,a,b,求以a开头b结尾的本质不同的字符串数. 由于n不算大,用hash就可以搞,不过这道题是存在复杂度$O(nlogn)$ ...

  2. BZOJ.3238.[AHOI2013]差异(后缀自动机 树形DP/后缀数组 单调栈)

    题目链接 \(Description\) \(Solution\) len(Ti)+len(Tj)可以直接算出来,每个小于n的长度会被计算n-1次. \[\sum_{i=1}^n\sum_{j=i+1 ...

  3. Codeforces 1061C (DP+滚动数组)

    题面 传送门 分析 考虑DP 设\(dp[i][j]\)表示前i个数选出的序列长度为j的方案数 状态转移方程为: \[ dp[i][j]= \begin{cases}dp\left[ i-1\righ ...

  4. Codeforces Round #422 (Div. 2) E. Liar 后缀数组+RMQ+DP

    E. Liar     The first semester ended. You know, after the end of the first semester the holidays beg ...

  5. Codeforces Good Bye 2015 D. New Year and Ancient Prophecy 后缀数组 树状数组 dp

    D. New Year and Ancient Prophecy 题目连接: http://www.codeforces.com/contest/611/problem/C Description L ...

  6. Codeforces 1063F - String Journey(后缀数组+线段树+dp)

    Codeforces 题面传送门 & 洛谷题面传送门 神仙题,做了我整整 2.5h,写篇题解纪念下逝去的中午 后排膜拜 1 年前就独立切掉此题的 ymx,我在 2021 年的第 5270 个小 ...

  7. 【bzoj5073】[Lydsy1710月赛]小A的咒语 后缀数组+倍增RMQ+贪心+dp

    题目描述 给出 $A$ 串和 $B$ 串,从 $A$ 串中选出至多 $x$ 个互不重合的段,使得它们按照原顺序拼接后能够得到 $B$ 串.求是否可行.多组数据. $T\le 10$ ,$|A|,|B| ...

  8. Codeforces 432D Prefixes and Suffixes (KMP、后缀数组)

    题目链接: https://codeforces.com/contest/432/problem/D 题解: 做法一: KMP 显然next树上\(n\)的所有祖先都是答案,出现次数为next树子树大 ...

  9. Codeforces Round #246 (Div. 2) D. Prefixes and Suffixes(后缀数组orKMP)

    D. Prefixes and Suffixes time limit per test 1 second memory limit per test 256 megabytes input stan ...

随机推荐

  1. [Linux] 60s快速分析Linux性能

    转载: https://www.cnblogs.com/zichuan/p/10440617.html 之前在地铁上看到过一篇快速分析Linux系统性能的文章,觉得以后有用,今天就找了一下,转载过来. ...

  2. Problems with Localtime

    http://pytz.sourceforge.net/#problems-with-localtime https://docs.djangoproject.com/en/2.2/topics/i1 ...

  3. web常用服务架构

    架构风格就是一种项目的设计模式.常见的架构风格有基于客户端与服务端的.基于组件模型的(EJB).分层架构(MVC).面向服务架构(SOA)等. 一.单体架构 单体架构也称为单体系统或单体应用,就是一种 ...

  4. 六、postman做ui测试

    一.思路 发请求去拿到网站的响应——>html 解析html标签,判断一些元素是否显示 二.目的 快速检查ui是否正确 三.用到的库 Cheerio https://cheerios.js.or ...

  5. python设置socket的超时时间(可能使用locust压测千级并发的时候要用到,先记录在此)

    在使用urllib或者urllib2时,有可能会等半天资源都下载不下来,可以通过设置socket的超时时间,来控制下载内容时的等待时间. 如下python代码 import socket timeou ...

  6. 【源码解析】Flink 是如何基于事件时间生成Timestamp和Watermark

    生成Timestamp和Watermark 的三个重载方法介绍可参见上一篇博客: Flink assignAscendingTimestamps 生成水印的三个重载方法 之前想研究下Flink是怎么处 ...

  7. Element 'repository' cannot have character [children], because the type's content type is element-only.

    出错现象 由于代码是网络上拷贝来的,可能存在特殊字符,在进行maven打包的时候报错 [ERROR] Malformed POM F:\ai开放平台\SRC\web知识产权申请\pom.xml: ex ...

  8. Dockerfile构建nginx镜像

    Dockerfile构建nginx镜像 [root@bogon ~]# mkdir /opt/docker-file [root@bogon ~]# cd /opt/docker-file/ [roo ...

  9. 【使用kubectl apply xxx.yaml的方式从docker源拉取镜像】

    只需要修改黄底色部分就可以了 apiVersion: apps/v1 # Kubernetes version 1.8.x should use apps/v1beta2 # Kubernetes v ...

  10. JS正则验证6位数字组成,验证纯中文组成

    常见的简单规则还有6位数字组成的密码,如果想要6位数字以上,第二个参数可以不设置.验证是否是纯中文,可以用Unicode字符区间,在网上找到了验证中文的表达式,然后查了查看Unicode编码的表格,这 ...