P4022 [CTSC2012]熟悉的文章

P4022 [CTSC2012]熟悉的文章

题目大意

$m$个文本,$n$个模式串

对于每个模式串:

求最大L使得该串能分解成不小于$L$的子串,且在文本中出现的长度不小于该串总长度的$90%$

建广义后缀树

对于$L_1$,$L_2$两种情况,$L_1>L_2$,如果$L_1$符合,显然$L_2$一定符合

发现没有,答案是单调的,用二分$check$

$dp_i$为前$i$个字符能匹配的最大长度

$dp_i=max\{dp[j]+i-j\}$转换后$dp_i=max\{(dp[j]-j)+i\}$用单调队列维护就行

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());
	}
}

  

原文地址:https://www.cnblogs.com/y2823774827y/p/10122570.html

时间: 2024-10-21 22:54:50

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

Luogu P4022 [CTSC2012]熟悉的文章

广义 \(SAM\) + 二分答案 + 单调队列优化 \(DP\) 对作文库建广义 \(SAM\) ,然后求出作文每个位置的最长匹配 \(d[i]\),然后二分答案 \(md\),然后 \(DP\) ,\(f[i]\) 表示到 \(i\) 的最大匹配长度,有 \(f[i]=\max(f[j]-j+i),j\in[i-d[i],i-md]\),最后检查 \(f[n]\geq 0.9\times len\) #include<iostream> #include<cstdio> #in

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

bzoj luogu 题目描述 阿米巴是小强的好朋友. 在小强眼中,阿米巴是一个作文成绩很高的文艺青年.为了获取考试作文的真谛,小强向阿米巴求教.阿米巴给小强展示了几篇作文,小强觉得这些文章怎么看怎么觉得熟悉,仿佛是某些范文拼拼凑凑而成的.小强不禁向阿米巴投去了疑惑的眼光,却发现阿米巴露出了一个狡黠的微笑. 为了有说服力地向阿米巴展示阿米巴的作文是多么让人觉得"眼熟",小强想出了一个评定作文 "熟悉程度"的量化指标\(L_0\).小强首先将作文转化成一个01串.之后

bzoj 2806: [Ctsc2012]Cheat 熟悉的文章

[题意] [题解] fhq自己写的题解就很清楚啦 (里面有关于神秘的阿米巴同学的介绍哦!很帅的样子,,, 我再来理一下思路 这道题思路应该是很简单很常规的,,但我做题太少辣! 二分一下肯定是必要的, 下面是判断是否可行的问题. 容易想到 要开一个 f 数组 表示 扫到了 第 i 位时 能匹配上多少个字母, 最后答案就是 f[lenth] * 10 >= lenth * 9 啦 f[i] 显然可以 通过 f[j] 转移 (j <= i - 二分出的下限的长度 + 1  且s[j……i]出现在字典

整理阅读的论文(三)

数学之所以有高声誉,其中一个理由就是数学使得自然科学实现定理化,给予自然科学某种程度的可靠性.                                                                                                                                                                        --阿尔伯特·爱因斯坦 网格优化已经被讨论了很多,这篇文章的主要亮点在

【转载】支持向量机(五)SMO算法

支持向量机(五)SMO算法 11 SMO优化算法(Sequential minimal optimization) SMO算法由Microsoft Research的John C. Platt在1998年提出,并成为最快的二次规划优化算法,特别针对线性SVM和数据稀疏时性能更优.关于SMO最好的资料就是他本人写的<Sequential Minimal Optimization A Fast Algorithm for Training Support Vector Machines>了. 我拜

Windows Azure Service Bus (4) Service Bus Queue和Storage Queue的区别

<Windows Azure Platform 系列文章目录> 熟悉笔者文章的读者都了解,Azure提供两种不同方式的Queue消息队列: 1.Azure Storage Queue 具体可以参考:       Windows Azure Cloud Service (12) PaaS之Web Role, Worker Role, Azure Storage Queue(下) Azure Storage Queue提供基础的消息队列服务,例如AddMessage, DeleteMessage.

Linux(Centos、Debian)之安装Java JDK及注意事项(转)

--转自:http://www.cnblogs.com/hanyinglong/p/5025635.html 说明:本人是以Debian 操作系统来进行安装的,这篇文章有很大帮助,才学Linux对有些命令不太熟悉,文章中有的命令我自己没有运行成功: 例如命令:cd usr/local/   mkdir kencery   cd kencery/  执行后没有找到目录 我是这样写的:cd /usr/local/   mkdir kencery     区别就是前面多 “/” 应该是 自己目录路径出

DDD实战进阶第一波(十五):开发一般业务的大健康行业直销系统(总结篇)

原文:DDD实战进阶第一波(十五):开发一般业务的大健康行业直销系统(总结篇) 前面我们花了14篇的文章来给大家介绍经典DDD的概念.架构和实践.这篇文章我们来做一个完整的总结,另外生成一个Api接口文档. 一.DDD解决传统的开发的几大问题: 没有描述需求的设计模型:而是直接通过数据库表的方式体现,也就是需求与设计是脱节的. 编码的架构也没有与设计和需求对应起来. 业务逻辑与技术混在一起:业务逻辑可能直接调用的数据访问,这样把业务逻辑与数据访问的技术混在一起. 开发没有层次感和节奏感:系统没有

ios影视项目解析 主要为讲block的细节 如果了解了 block的定义等 但是对运用不是很熟悉可以参考本文章

源于github上的影视项目解析 此项目在4app  和  github上都可以下载 项目截图: 此处为程序刚运行界面 程序应有一个discover控制器 找到discover控制器,然后可以根据项目的流程熟悉此项目的原理,从而学习到他们的架构思想 1 - (void)setupTableView 2 { 3 if (!_refreshControl) 4 { 5 _refreshControl = [[UIRefreshControl alloc] initWithFrame:CGRectMa