首页 > 其他分享 >SP10570 LONGCS - Longest Common Substring

SP10570 LONGCS - Longest Common Substring

时间:2023-10-27 15:24:19浏览次数:40  
标签:LONGCS 500020 -- SP10570 len height Substring sa col

SP10570 LONGCS - Longest Common Substring

更好的阅读体验

提供一个后缀数组解法。

多字符串,中间加分隔符然后后缀排序求出 \(sa\) 和 \(height\)。把每个字符串对应的位置染上颜色,问题变为寻找 \(i,j\) 使得区间 \([i,j]\) 包含 \(n\) 种颜色并且 \(\min_{k=i+1}^{j}height_k\) 最大。可以从后向前扫一遍,枚举左端点,寻找合法的最靠左的右端点,颜色数可以开桶维护。对于区间 \(\min\),由于左右端点单调不增,所以可以单调队列。复杂度 \(\mathcal O(len\log len+len)\),瓶颈在于后缀排序。

	int T,n,m,len,le,maxn,col[500020],height[500020],sa[500020],rk[500020],x[500020],xx[500020],y[500020],t[500020];
	char s[500020];
	deque<int> q;
	inline void mian()
	{
		read(T);
		while(T--)
		{
			read(n),m=128,memset(col,0,sizeof(col)),len=maxn=0,memset(t,0,sizeof(t));
			for(int i=1;i<=n;++i)
			{
				scanf("%s",s+1),le=strlen(s+1);
				for(int j=1;j<=le;++j)++t[x[++len]=s[j]],col[len]=i;
				if(i!=n)++t[x[++len]=++m];
			}
			if(n==1){write(le,'\n');continue;}
			memcpy(xx,x,sizeof(x)),swap(n,len);
			for(int i=2;i<=m;++i)t[i]+=t[i-1];
			for(int i=1;i<=n;++i)sa[t[x[i]]--]=i;
			for(int k=1,num=0;k<=n;k<<=1,num=0)
			{
				for(int i=n;i>n-k;--i)y[++num]=i;
				for(int i=1;i<=n;++i)if(sa[i]>k)y[++num]=sa[i]-k;
				for(int i=1;i<=m;++i)t[i]=0;
				for(int i=1;i<=n;++i)++t[x[i]];
				for(int i=1;i<=m;++i)t[i]+=t[i-1];
				for(int i=n;i>=1;--i)sa[t[x[y[i]]]--]=y[i];
				swap(x,y),x[sa[1]]=1;
				for(int i=2;i<=n;++i)
				{
					if(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k])x[sa[i]]=x[sa[i-1]];
					else x[sa[i]]=x[sa[i-1]]+1;
				}
				if((m=x[sa[n]])==n)break;
			}
			for(int i=1;i<=n;++i)rk[sa[i]]=i;
			for(int i=1,k=0;i<=n;k?--k:0,++i)
			{
				while(xx[i+k]==xx[sa[rk[i]-1]+k])++k;
				height[rk[i]]=k;
			}
			memset(t,0,sizeof(t));
			while(!q.empty())q.pop_back();
			for(int i=n-len+1,sum=0,r=n-len+1;i>=1;--i)
			{
				if(col[sa[i]]&&!t[col[sa[i]]]++)++sum;
				while(r>=i&&sum==len&&t[col[sa[r]]]!=1)--t[col[sa[r--]]];
				while(!q.empty()&&q.front()>r)
				q.pop_front();
				if(sum==len)maxn=max(maxn,height[q.front()]);
				while(!q.empty()&&height[q.back()]>height[i])q.pop_back();
				q.eb(i);
			}
			write(maxn,'\n');
		}
	}

标签:LONGCS,500020,--,SP10570,len,height,Substring,sa,col
From: https://www.cnblogs.com/WrongAnswer90-home/p/17792427.html

相关文章

  • Codeforces Round 685 (Div. 2) B. Non-Substring Subsequence
    对于一个长为\(n\)的\(01\)字符串\(s\)有\(n\)个询问。第\(i\)个询问被\(l_i,r_i\)描述\(1\leql_i<r_i\leqn\)。对于每个询问,你需要确定\(s\)中是否存在一个子序列等同于子串\(s[l_i\cdotsr_i]\)。显然子序列可以和子串仅有一个字符不相同。于是\(s......
  • CF938F Erasing Substrings 题解
    ErasingSubstrings一个神奇的想法是设\(f_{i,j}\)表示在位置\([1,i]\)中,我们删去了长度为\(2^k(k\inj)\)的一些串,所能得到的最小字典序。使用二分加哈希可以做到\(O(n^2\log^2n)\),无法承受。发现对于状态\(f_{i,j}\),它已经确定了\(i-j\)位的串,因为所有\(\inj\)......
  • xpath 处理自增的id manage11 使用表达式 //*[starts-with(@id, "manage") and
      //*[starts-with(@id,"manage")andnumber(substring-after(@id,"manage"))=11] 1.使用starts-with()函数选择以"manage"开头的所有元素,2.使用substring-after()函数获取ID中"manage"后面的部分。3.使用number()函数将这部分转换为数字,4.使用逻辑运算符and来判断......
  • [ARC165D] Substring Comparison
    ProblemStatementForanintegersequence$X=(X_1,X_2,\dots,X_n)$,let$X[L,R]$denotetheintegersequence$(X_L,X_{L+1},\dots,X_{R})$.Youaregivenintegers$N$and$M$,and$M$quadruplesofintegers$(A_i,B_i,C_i,D_i)$.Determineifthereisaninte......
  • 一次性搞懂JS字符串截取方法substring()、slice()以及substr()的用法和区别
    substring()和slice()都接受两个参数,“start”和“end”。“start”表示截取的开始位置,“end”表示结束的位置(不包括该位置的字符,也就是前要后不要)。如果不传参数,则返回字符串本身的一个副本。 如果只传一个参数,则从该位置开始,截取到字符串的末尾。 如果传递两个参数,则......
  • CF914F Substrings in a String
    知识点:bitset,SAM,根号分治Link:https://codeforces.com/problemset/problem/914/F一种在字符集较小情况下的多轮字符串匹配暴力的优化。好久没写过单题的题解了格式都忘了、、、简述给定一仅包含小写字母的字符串\(s\),给定\(q\)次操作,每次操作都是下列两种形式之一:将字符......
  • MySQL字符串截取之substring_index
    substring_index(str,delim,count)str:要处理的字符串delim:分隔符count:计数 例子:str=www.wikibt.comsubstring_index(str,'.',1)结果是:wwwsubstring_index(str,'.',2)结果是:www.wikibt也就是说,如果count是正数,那么就是从左往右数,第N个分隔符的左边的全部内容相......
  • 数据库PostgreSQL PG 字符串拼接,大小写转换,substring
    前言PostgreSQL数据库简称pg数据库。本文主要介绍使用pg数据库时,字符串的一些常用操作。例如:多个字符串如何连接在一起,字符串如何大小写转换,删除字符串两边的空格,查找字符位置,查找子字符串等。一、多个字符串如何连接,拼接?pg的字符串连接使用||,注意不是+1.将2个字符串hello......
  • SPOJ Substrings 题解
    \(\text{SAM}\)入门好题。首先我们需要知道几个关于\(\text{SAM}\)的结论。结论1:题目中的\(f(x)\)单调下降。显然,对于长度为\(x\)的子串,其必存在一个\(x-1\)的后缀,这个后缀的\(\text{endpos}\)集合肯定包含子串的\(\text{endpos}\)集合,所以必有\(f(x-1)\le......
  • JS中字符串28种常用API总结,substring、slice、JSON.stringify、match、split、search
    一、引言在前端开发中,处理字符串是一项常见的任务。JavaScript提供了一系列的字符串API,用于操作和处理字符串数据。字符串常用的API方法有很多,包括查找字符串、截取字符串、替换字符串、分割字符串、大小写转换、字符串拼接和字符串比较等等。本文将介绍一些常用的字符串API......