bzoj

description

你有一个\(A\)串和\(B\)串,你需要判断是否可以在\(A\)串中拆出\(x\)个互不相交的子串,使它们按顺序拼在一起可以组成\(B\)串。

\(|A|,|B|\le10^5,x\le100\)

sol

设\(f_{i,j}\)表示已经使用了\(i\)个\(A\)的子串,\(A\)已经使用到了\(j\)位置时\(B\)串中的最长匹配的长度,每次转移的时候显然回取\(A\)串中的\(j+1\)位置和\(B\)串中的\(f_{i,j}+1\)位置的\(lcp\)进行转移,再做一个前缀\(\max\)就好了。

\(lcp\)用后缀数组做到\(O(n\log n)-O(1)\),复杂度\(O(T(n\log n+nx))\)

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int gi(){
int x=0,w=1;char ch=getchar();
while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if (ch=='-') w=0,ch=getchar();
while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return w?x:-x;
}
const int N = 2e5+5;
int T,n,m,K,len,val[N],t[N],x[N],y[N],SA[N],Rank[N],Height[20][N],lg[N],f[2][N];
char a[N],b[N];
bool cmp(int i,int j,int k){return y[i]==y[j]&&y[i+k]==y[j+k];}
void getSA(){
int m=30;
for (int i=0;i<=m;++i) t[i]=0;
for (int i=1;i<=len;++i) ++t[x[i]=val[i]];
for (int i=1;i<=m;++i) t[i]+=t[i-1];
for (int i=len;i;--i) SA[t[x[i]]--]=i;
for (int k=1;k<=len;k<<=1){
int p=0;
for (int i=0;i<=m;++i) y[i]=0;
for (int i=len-k+1;i<=len;++i) y[++p]=i;
for (int i=1;i<=len;++i) if (SA[i]>k) y[++p]=SA[i]-k;
for (int i=0;i<=m;++i) t[i]=0;
for (int i=1;i<=len;++i) ++t[x[y[i]]];
for (int i=1;i<=m;++i) t[i]+=t[i-1];
for (int i=len;i;--i) SA[t[x[y[i]]]--]=y[i];
swap(x,y);x[SA[1]]=p=1;
for (int i=2;i<=len;++i) x[SA[i]]=cmp(SA[i],SA[i-1],k)?p:++p;
if (p>=len) break;m=p;
}
for (int i=1;i<=len;++i) Rank[SA[i]]=i;
for (int i=1,j=0;i<=len;++i){
if (j) --j;
while (val[i+j]==val[SA[Rank[i]-1]+j]) ++j;
Height[0][Rank[i]]=j;
}
for (int i=2;i<=len;++i) lg[i]=lg[i>>1]+1;
for (int j=1;j<=lg[len];++j)
for (int i=1;i+(1<<j)-1<=len;++i)
Height[j][i]=min(Height[j-1][i],Height[j-1][i+(1<<j-1)]);
}
int lcp(int i,int j){
i=Rank[i],j=Rank[j];if (i>j) swap(i,j);
++i;int k=lg[j-i+1];
return min(Height[k][i],Height[k][j-(1<<k)+1]);
}
int main(){
T=gi();while (T--){
n=gi();m=gi();K=gi();scanf("%s",a+1);scanf("%s",b+1);
memset(Rank,0,sizeof(Rank));
for (int i=1;i<=n;++i) val[i]=a[i]-'a'+1;
for (int i=1;i<=m;++i) val[n+1+i]=b[i]-'a'+1;
val[n+1]=27;val[n+1+m+1]=0;len=n+m+1;getSA();
memset(f[0],0,sizeof(f[0]));
for (int i=1;i<=K;++i){
int now=i&1,pre=now^1;
memset(f[now],0,sizeof(f[now]));
for (int j=0;j<n;++j){
int gg=lcp(j+1,n+1+f[pre][j]+1);
f[now][j+gg]=max(f[now][j+gg],f[pre][j]+gg);
}
for (int j=1;j<=n;++j) f[now][j]=max(f[now][j],f[now][j-1]);
}
puts(f[K&1][n]==m?"YES":"NO");
}
return 0;
}

[BZOJ5073][Lydsy1710月赛]小A的咒语的更多相关文章

  1. [BZOJ5073] [Lydsy1710月赛]小A的咒语 后缀数组+dp+贪心

    题目链接 首先这种题一看就是dp. 设\(dp[i][j]\)表示\(A\)序列中到\(i\)位之前,取了\(j\)段,在\(B\)中的最长的长度. 转移也比较简单 \[ dp[i][j] \to d ...

  2. 5073 [Lydsy1710月赛]小A的咒语

    LINK:[Lydsy1710月赛]小A的咒语 每次给定两个串 要求从a串中选出x段拼成B串 能否做到.T组数据. \(n\leq 100000,m\leq 100000,T\leq 10,x\leq ...

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

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

  4. 【BZOJ5073】[Lydsy十月月赛]小A的咒语 DP(错解)

    [BZOJ5073][Lydsy十月月赛]小A的咒语 题解:沙茶DP,完全不用后缀数组. 用f[i][j]表示用了A的前i个字符,用了j段,最远能匹配到哪.因为显然我们能匹配到的地方越远越好,所以我们 ...

  5. [BZOJ 5072][Lydsy1710月赛]小A的树

    传送门 \(\color{green}{solution}\) 嗯...其实我也不太会,所以大胆猜个结论吧(后来证了一下,然后放弃了...). 我们发现如果要使一个联通块的黑点数量为\(k\)的方案最 ...

  6. BZOJ5072:[Lydsy1710月赛]小A的树(树形DP)

    Description BZOJ只是扔了个下载链接 Solution 设$f[x][i]$表示$x$点选中$i$个黑点的最小连通块. 设$g[x][i]$表示$x$点选中$i$个黑点的最大连通块. 转 ...

  7. [BZOJ 5074][Lydsy1710月赛]小B的数字

    传送门 \(\color{green}{solution}\) 设 \[b_{i}=2^{w_{i}},sum= \sum_{i=1}^{n}{w_{i}}\] 则对于任意\(a_{i}\)都有 \[ ...

  8. [Lydsy1710月赛] 小B的数字

    神TM 又又又又是构造题..... 很简单的化简就是,把2^k[i]都换成k[i] ,然后就可以得出 对于任意的i,k[i] * a[i] >= ∑k[]. 最优的构造肯定是使  k[i] = ...

  9. bzoj 5072 [Lydsy1710月赛]小A的树——树形dp

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=5072 发现对于每个子树,黑点个数确定时,连通块的大小取值范围一定是一段区间:所以考虑只最小化 ...

随机推荐

  1. Kafka分布式:ZooKeeper扩展

    [ZooKeeper] 服务注册.服务发现.客户端负载均衡.Offset偏移量分布式存储. kafka使用zookeeper来实现动态的集群扩展,不需要更改客户端(producer和consumer) ...

  2. 最新Dubbo-admin+Zookeeper搭建

    Zookeeper搭建: 下载zookeeper压缩包并解压,下载地址:http://www.apache.org/dyn/closer.cgi/zookeeper/进入conf目录下将 zoo_sa ...

  3. spring mvc:练习:表单验证(javaConfig配置和注解)

    使用Spring表单标签, 表单验证使用 JSR303 的验证注解,hibernate-validators,提供了使用MessageSource和访问静态资源(如CSS,JavaScript,图片) ...

  4. Oracle Solaris 11.4 GA 版发布,这将是 Solaris 的绝唱

    美国当地时间8月28日,Oracle 正式宣布推出 Oracle Solaris 11.4 GA 稳定版,距离上个版本 11.3 的发布已过去近三年.Oracle 的产品管理总监 Scott Lynn ...

  5. 什么是JSON?

    JSON是一种取代XML的数据结构,和xml相比,它更小巧但描述能力却不差,由于它的小巧所以网络传输数据将减少更多流量从而加快速度. JSON就是一串字符串 只不过元素会使用特定的符号标注. {} 双 ...

  6. 【转至nmap】nc命令

    什么是nc nc是netcat的简写,有着网络界的瑞士军刀美誉.因为它短小精悍.功能实用,被设计为一个简单.可靠的网络工具 nc的作用 (1)实现任意TCP/UDP端口的侦听,nc可以作为server ...

  7. MongoDB基于GridFS管理文件

    前言 GridFS是一种将大型文件存储在MongoDB的文件规范: 数据库支持以BSON格式保存二进制对象. 但是MongoDB中BSON对象最大不能超过4MB. GridFS 规范提供了一种透明的机 ...

  8. 二十 Python分布式爬虫打造搜索引擎Scrapy精讲—编写spiders爬虫文件循环抓取内容—meta属性返回指定值给回调函数—Scrapy内置图片下载器

    编写spiders爬虫文件循环抓取内容 Request()方法,将指定的url地址添加到下载器下载页面,两个必须参数, 参数: url='url' callback=页面处理函数 使用时需要yield ...

  9. SPOJ-CLEANRBT-状压dp

    CLEANRBT - Cleaning Robot #dynamic-programming #bfs Here, we want to solve path planning for a mobil ...

  10. MongoDB.Driver 2.4以上版本 在.NET中的基本操作

    MongoDB.Driver是操作mongo数据库的驱动,最近2.0以下版本已经从GitHub和Nuget中移除了,也就是说.NET Framework4.0不再能从官方获取到MongoDB的驱动了, ...