大意: 给定串$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. 【转】python requests库添加自定义cookie的方法

    requests库是个很方便的爬虫,相关文档已经很详细了.不过我今天在爬网页时,有一个网站是在脚本中添加cookie的,但我向requests.cookies里添加cookie费了不少周折.尝试了多个 ...

  2. Learning Conditioned Graph Structures for Interpretable Visual Question Answering

    Learning Conditioned Graph Structures for Interpretable Visual Question Answering 2019-05-29 00:29:4 ...

  3. 【转载】迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好文章(快快珍藏)

    原文链接:https://www.cnblogs.com/lixinjie/p/10811219.html 常规的误区 假设有一个展示用户详情的需求,分两步,先调用一个HTTP接口拿到详情数据,然后使 ...

  4. XML 中的 xmlns 等属性的意义

    原文:https://blog.csdn.net/lengxiao1993/article/details/77914155 Maven 是一个 java 开发人员很难绕过的构建工具, 因为有众多的开 ...

  5. MyBatis:MyBatis操作MySQL存储过程

    一 . 数据库中创建存储过程,并查看创建结果 1.创建存储过程 DROP procedure IF EXISTS net_procedure_request; DELIMITER $$ )) BEGI ...

  6. flutter中使用shared_preferences的存储

    添加依赖 shared_preferences: ^+ 工具类 import 'dart:async'; import 'package:shared_preferences/shared_prefe ...

  7. 【转载】 clusterdata-2011-2 谷歌集群数据分析(二)--task_usage

    原文地址: https://blog.csdn.net/yangss123/article/details/78298749 由于原文声明其原创文章不得允许不可转载,故这里没有转载其正文内容. --- ...

  8. Qt编写气体安全管理系统23-类型设置

    一.前言 类型设置这个功能模块大大拓展了整个系统的灵活性,将整个系统中所有用到的控制器型号.探测器数量.探测器型号.气体种类.气体符号都存储到数据库表中,用户在类型设置中可以自由添加删除和修改,这样后 ...

  9. word xml 各个标签含义

    @参考文章 <w:p> <!--表示一个段落--> <w:val > <!--表示一个值--> <w:r> <!--表示一个样式串,指 ...

  10. HTML布局排版2如何设置div总是相对于页面居中

    由于浏览器页面有大有小,为了适应浏览器宽度,可以让div总是对于浏览器居中,设置div左右两边的margin为auto可以实现这个效果.如图,第一个是默认div,无上下左右外边距,第二个是设置了mar ...