大意: 给定串$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. iview3 版本 升级

    Button 废弃 type ghost,原先的 default 样式有改变. Icon 的图标升级至 ionicons 3.0 图标,图标名称有改变. Breadcrumb 废弃 href 属性. ...

  2. win10安装Navicat 12 for MySQL

    Navicat 下载地址: https://blog.csdn.net/u013600314/article/details/80605981 Navicat 连接Mysql 的方法:https:// ...

  3. No value specified for Date

    现象 使用BeanUtils复制对象属性,结果抛出No value specified for Date异常. 原因 是数据源orig有一个参数是java.util.Date类型,没有初始化值,调用了 ...

  4. lintcode 394. Coins in a Line 、leetcode 292. Nim Game 、lintcode 395. Coins in a Line II

    变型:如果是最后拿走所有石子那个人输,则f[0] = true 394. Coins in a Line dp[n]表示n个石子,先手的人,是必胜还是必输.拿1个石子,2个石子之后都是必胜,则当前必败 ...

  5. prometheus + influxdb + grafana + mysql

    前言 本文介绍使用influxdb 作为prometheus持久化存储和使用mysql 作为grafana 持久化存储的安装方法 一 安装go环境 如果自己有go环境可以自主编译remote_stor ...

  6. ISO/IEC 9899:2011 条款6.9——外部定义

    6.9 外部定义 语法 1.translation-unit: external-declaration translation-unit    external-declaration extern ...

  7. Jmeter 时间函数工具汇总

    在使用Jmeter过程中,常使用的函数汇总 __time : 获取时间戳.格式化时间 ${__time(yyyy-MM-dd HH:mm:ss:SSS,time)}  :格式化生成时间格式 2018- ...

  8. 004-行为型-10-中介者模式(Mediator)

    一.概述 在Mediator模式中,类之间的交互行为被统一放在Mediator的对象中,对象通过Mediator对象同其他对象交互,Mediator对象起着控制器的作用. 用一个中介对象来封装一系列的 ...

  9. ERROR 1130:mysql 1130连接错误的有效解决方法

    今天在用sqlyog连接非本地的Mysql服务器的数据库,居然无法连接很奇怪,报1130错误, ERROR 1130: Host 192.168.3.100 is not allowed to con ...

  10. 【440】Tweet 元素意义

          参考:Tweet Object 参考:Geo Objects 参考:User Object Ref: Place data dictionary Tweet Object Attribut ...