题目

P4022 [CTSC2012]熟悉的文章

题目大意:多个文本串,多个匹配串,我们求\(L\),\(L\)指(匹配串中\(≥L\)长度的子串出现在文本串才为"熟悉",使得匹配串整个近似"熟悉")的最大值

近似"熟悉":将匹配串分割,所有串总"熟悉"长度有\(90\%\)以上

做法

首先明确一点,\(L_1<L_2\),则\(L_1\)的熟悉程度\(≥L_2\)的熟悉程度

比如文本串\('adc'\),匹配串\('ac'\),\(L=2\)熟悉程度为\(0\%\),\(L=1\)熟悉程度为\(100\%\)

故我们可以二分\(L\)然后去\(dp\),设数组\(dp_i\)为以\(i\)结尾前的熟悉长度

则:\(dp_i=max\{dp_j+(i-j)\}(j\in [i-match_i,i-L])\),其中\(match_i\)是以\(i\)结尾的后缀所能匹配的最长长度

\(i-match_i\)和\(i-L\)都是单调递增的,单调队列优化一下

\(O(nlogn)\)

My complete code

几个月前惨不忍睹的码风虽然现在依旧是,将就看吧

#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
typedef long long LL;
const LL maxn=400000;
LL n,m,nod=1,last,Len;
LL len[maxn],son[maxn][26],fail[maxn],val[maxn],dp[maxn];
char s[maxn];
inline void Insert(LL c){
LL p=last,np=++nod;
last=np;
len[np]=len[p]+1;
while(p&&!son[p][c]){
son[p][c]=np;
p=fail[p];
}
if(!p)
fail[np]=1;
else{
LL q=son[p][c];
if(len[q]==len[p]+1)
fail[np]=q;
else{
LL nq=++nod;
len[nq]=len[p]+1;
memcpy(son[nq],son[q],sizeof(son[q]));
fail[nq]=fail[q];
fail[q]=fail[np]=nq;
while(p&&son[p][c]==q){
son[p][c]=nq;
p=fail[p];
}
}
}
}
inline void Match(){
LL now=1,l=0;
for(LL i=1;i<=Len;++i){
LL c=s[i]-'0';
while(now&&!son[now][c]){
now=fail[now];
l=len[now];
}
if(now){
now=son[now][c];
++l;
}else{
now=1;
l=0;
}
val[i]=l;
}
}
inline bool check(LL L){
LL head=1,tail=0;
LL que[maxn];
for(LL i=1;i<=L-1;++i)
dp[i]=0;
for(LL i=L;i<=Len;++i){
while(head<=tail&&dp[que[tail]]-que[tail]<dp[i-L]-(i-L))
--tail;
que[++tail]=i-L;
while(head<=tail&&que[head]<i-val[i])
++head;
dp[i]=dp[i-1];
if(head<=tail)
dp[i]=max(dp[i],dp[que[head]]-que[head]+i);
}
return dp[Len]*10>=Len*9;
}
inline LL Solve(){
LL l=1,r=Len,ans=0;
Match();
while(l<=r){
LL mid=(l+r)>>1;
if(check(mid)){
ans=mid;
l=mid+1;
}else
r=mid-1;
}
return ans;
}
int main(){
scanf("%lld%lld",&n,&m);
while(m--){
scanf(" %s",s+1);
Len=strlen(s+1);
last=1;
for(LL i=1;i<=Len;++i)
Insert(s[i]-'0');
}
while(n--){
scanf(" %s",s+1);
Len=strlen(s+1);
printf("%lld\n",Solve());
}
}

P4022 [CTSC2012]熟悉的文章的更多相关文章

  1. [CTSC2012]熟悉的文章(后缀自动机+动态规划)

    题目描述 阿米巴是小强的好朋友. 在小强眼中,阿米巴是一个作文成绩很高的文艺青年.为了获取考试作文的真谛,小强向阿米巴求教.阿米巴给小强展示了几篇作文,小强觉得这些文章怎么看怎么觉得熟悉,仿佛是某些范 ...

  2. 【[CTSC2012]熟悉的文章】

    题目 好题啊 \(SAM\)+单调队列优化\(dp\) 首先这个\(L\)满足单调性真是非常显然我们可以直接二分 二分之后套一个\(dp\)就好了 设\(dp[i]\)表示到达\(i\)位置熟悉的文章 ...

  3. [BZOJ2806][CTSC2012]熟悉的文章(Cheat)

    bzoj luogu 题目描述 阿米巴是小强的好朋友. 在小强眼中,阿米巴是一个作文成绩很高的文艺青年.为了获取考试作文的真谛,小强向阿米巴求教.阿米巴给小强展示了几篇作文,小强觉得这些文章怎么看怎么 ...

  4. 题解-CTSC2012 熟悉的文章

    Problem bzoj 题目大意:给定多个标准串和一个文本串,全部为01串,如果一个串长度不少于\(L\)且是任意一个标准串的子串,那么它是"熟悉"的.对于文本串\(A\),把\ ...

  5. CTSC2012 熟悉的文章

    传送门 首先很容易想到对于所有的模式串建出广义后缀自动机,之后对于我们每一个要检查的文本串,先在SAM上跑,计算出来每一个位置能匹配到的最远的位置是多少.(就是当前点减去匹配长度) 之后--考虑DP- ...

  6. Luogu4022 CTSC2012 熟悉的文章 广义SAM、二分答案、单调队列

    传送门 先将所有模板串扔进广义SAM.发现作文的\(L0\)具有单调性,即\(L0\)更小不会影响答案,所以二分答案. 假设当前二分的值为\(mid\),将当前的作文放到广义SAM上匹配. 设对于第\ ...

  7. [CTSC2012]熟悉的文章 (后缀自动机 单调队列)

    /* 首先答案显然是具有单调性的, 所以可以二分进行判断 然后当我们二分过后考虑dp来求最长匹配个数, 发现每个点能够转移的地点 肯定是一段区间, 然后这样就能够得到一个log^2算法 至于每个点的匹 ...

  8. [CTSC2012]熟悉的文章 后缀自动机

    题面:洛谷 题解: 观察到L是可二分的,因此我们二分L,然后就只需要想办法判断这个L是否可行即可. 因为要尽量使L可行,因此我们需要求出对于给定L,这个串最多能匹配上多少字符. 如果我们可以对每个位置 ...

  9. Luogu-4022 [CTSC2012]熟悉的文章

    广义后缀自动机+DP 对于作文库建出广义后缀自动机,广义自动机就是在每次添加一个字符串之前把\(last=0\),然后正常添加就好了 对于每个询问串,预处理出每个位置\(i\)能向前匹配的最长长度\( ...

随机推荐

  1. JAVA静态导入(inport static)详解

    在Java 5中,import语句得到了增强,以便提供甚至更加强大的减少击键次数功能,虽然一些人争议说这是以可读性为代价的.这种新的特性成为静态导入. 当你想使用static成员时,可以使用静态导入( ...

  2. 谈一谈Http Request 与Http Response

    1.什么是HTTPRequest与HTTP Response? 我们平时打开浏览器,输入网址,点击Enter按键,然后我们想要的网页就呈现在我们的眼前,可是这个过程是怎么实现的呢? 简单来说是这样的: ...

  3. (三)spark算子 分为3大类

    ation算子通过sparkContext执行提交作业的runJob,触发rdd的DAG执行 (foreach) foreach(f) 会对rdd中的每个函数进行f操作,下面的f操作就是打印输出没有元 ...

  4. spark sql的简单操作

    测试数据 sparkStu.text zhangxs chenxy wangYr teacher wangx teacher sparksql { ,"job":"che ...

  5. 使用GnuPG(PGP)加密信息及数字签名教程_转

    所谓加解密就是一方以密钥加密,另一外收到文件后以相对应的密钥解密,从而获取原始文件.数字签名的过程:信息是通过普通未加密方式发送信息给对方的,只是在每条信息后面都会附加一坨字符(名曰:签名)(或信息与 ...

  6. docker-maven-plugin

    顾名思义,docker-maven-plugin是一个docker的maven插件,用来执行docker镜像的制作和上传,他的地址是https://github.com/spotify/docker- ...

  7. junit spring 测试

    http://my.oschina.net/dlpinghailinfeng/blog/336694 http://blog.csdn.net/zhangzikui/article/details/1 ...

  8. html5小趣味知识点系列(一)required

    都知道这个属性是检查你 是否填写了字段也就是说咱们不用判断输入的数值是否为空的情况了 但是这个属性一定要和form配合在一起使用单独的使用是不可以实现的 <!DOCTYPE html> & ...

  9. Linux下文件的基本操作

    文件的基本操作 新建和删除文件夹 命令#mkdir /file 在当前目录创建file文件夹 命令#rmdir /file 删除当前目录下file文件夹 复制和移动文件 命令#cp text/file ...

  10. Apache禁止ip访问

    网站突然让禁止ip访问,于是就通过配置Apache达到了想要的效果. 我们网站用的是Apache+tomcat集群,所以需要配置虚拟主机,虚拟主机我在这里就不说了,不明白的上网搜搜吧,这里只说禁止ip ...