首先这个题目显然是要二分转换成判断可行性的

之后我们考虑DP

设f(i)表示 1->i 熟悉的子串的长度的最大值

那么对于i这个点,要么不在熟悉的子串中,要么在熟悉的子串中

所以得到

f(i)=max(f(i-1),f(j)+i-j);

其中i-j是划分的熟悉的子串的长度,要满足以下条件:

1、i-j>=k (k为二分出来的值)

2、[j+1,i]这段串是给定标准文章库的一个子串

我们又知道若[j+1,i]是一个满足条件的子串,那么[j+2,i]也一定满足条件

假设我们已知最小的p满足[p+1,i]是一个满足条件的子串,定义L=i-p

那么条件2转化为 i-j<=L

求特定区间的最大值,且左右端点是单调的,我们是可以用单调队列的

那么现在问题就是求解最小的p使得[p+1,i]满足条件

即求解给定串S的一个前缀的最长满足条件的后缀,这时可以用后缀自动机做的

每次只需要在上次的基础上顺着parent树向上寻找匹配就可以了

注意:当寻找到SAM上的一个可匹配的节点时,当前的L并不一定是这个合法节点的len值+1

因为SAM上的节点的len值为其可以取得的长度的最大值,它有可能比上一次的L要大

所以我的代码对这种情况进行了一下处理QAQ

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cstdlib>
#include<algorithm>
using namespace std; const int maxn=1100010;
int n,m,cnt,la,len;
char s[maxn];
struct Node{
int next[3];//0 1 2
int len,link;
}st[maxn<<1];
int Q[maxn],h,t;
int f[maxn]; void init(){
cnt=la=0;
st[0].link=-1;
}
void add(int c){
int cur=++cnt;
st[cur].len=st[la].len+1;
int p;
for(p=la;p!=-1&&st[p].next[c]==0;p=st[p].link)st[p].next[c]=cur;
if(p==-1)st[cur].link=0;
else{
int q=st[p].next[c];
if(st[q].len==st[p].len+1)st[cur].link=q;
else{
int clone=++cnt;
st[clone]=st[q];
st[clone].len=st[p].len+1;
for(;p!=-1&&st[p].next[c]==q;p=st[p].link)st[p].next[c]=clone;
st[q].link=st[cur].link=clone;
}
}la=cur;
}
bool check(int k){
h=1;t=0;f[0]=0;
int p=0,L=0;
for(int i=1;i<=len;++i){
if(i>=k){
while(h<=t&&f[Q[t]]-Q[t]<f[i-k]-(i-k))t--;
Q[++t]=i-k;
}
int now=s[i]-'0';
int cur=p;
for(;p!=-1&&st[p].next[now]==0;p=st[p].link);
f[i]=f[i-1];
if(p==-1){p=0;L=0;continue;}
if(p==cur)L++;
else L=st[p].len+1;
p=st[p].next[now];
while(h<=t&&i-Q[h]>L)h++;
if(h<=t)f[i]=max(f[i],f[Q[h]]-Q[h]+i);
}return len*9<=f[len]*10;
} int main(){
scanf("%d%d",&n,&m);init();
for(int i=1;i<=m;++i){
scanf("%s",s+1);len=strlen(s+1);
for(int j=1;j<=len;++j)add(s[j]-'0');
add(2);
}
while(n--){
scanf("%s",s+1);len=strlen(s+1);
int L=0,R=len;
while(L<R){
int mid=L+((R-L+1)>>1);
if(check(mid))L=mid;
else R=mid-1;
}printf("%d\n",L);
}return 0;
}

  

最新文章

  1. 挑子学习笔记:两步聚类算法(TwoStep Cluster Algorithm)——改进的BIRCH算法
  2. 读书笔记---《火球:UML大战需求分析》
  3. Maven dependency spring-web vs spring-webmvc
  4. 利用AuthorizeAttribute属性简单避免 MVC 中的跨域攻击
  5. 表单插件——form
  6. NFC(8)关于新买的标签的格式化
  7. C# 之 SqlConnection 类
  8. Android no such table (找不到表)
  9. java使用dom4j和XPath解析XML与.net 操作XML小结
  10. cocos2d-x学习资源汇总(持续更新。。。)
  11. display:block;inline;inline-block大总结
  12. Lua5.3 注册表 _G _ENV
  13. hdu 2196 Computer(树形DP经典)
  14. 使用spring-session共享springmvc项目的session
  15. nrf2401 - 最廉价的2.4G无线通信方案
  16. 【论文笔记】Spatial Temporal Graph Convolutional Networks for Skeleton-Based Action Recognition
  17. rabbitmq安装.教程
  18. Oracle11gR2
  19. PLSQL启动很慢的问题
  20. Spring Cloud(二):Spring Cloud Eureka Server高可用注册服务中心的配置

热门文章

  1. 为oracle中的表格增加列和删除列
  2. Hyper-V 虚拟机连接外部网络
  3. 使用DNSSCrypt解决DNS污染问题
  4. 一次GC问题定位
  5. mysql 主从同步 Last_SQL_Error
  6. HTTP 错误 404.2 解决方案
  7. Jquery实现简单的分页
  8. mac安装memcache
  9. [Linux]学习笔记(3)-uname的用法
  10. Linux系统下ssh的相关配置详细解析