后缀数组 LCP--模板题
题意:
给你S串和T串,用T串的所有前缀去匹配S串(匹配值是最长公共子串)。
问你总值相加是多少。
思路:
先把两个S,T串倒过来,再拼接 S#T 合成一串,跑一下后缀数组
在排序好的rank里计算每个T后缀的最长匹配长度。(前后两个for即可)
最后dp对后缀取max,累计答案。(因为后缀从pos开始的ans1肯定被后缀从pos-1开始的ans2包含,所以如果ans2<ans1,那要对ans2取max(ans1)
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#include <cstdio>//sprintf islower isupper
#include <cstdlib>//malloc exit strcat itoa system("cls")
#include <iostream>//pair
#include <fstream>//freopen("C:\\Users\\13606\\Desktop\\草稿.txt","r",stdin);
#include <bitset>
//#include <map>
//#include<unordered_map> https://www.nitacm.com/problem_show.php?pid=585
#include <vector>
#include <stack>
#include <set>
#include <string.h>//strstr substr
#include <string>
#include <time.h>//srand(((unsigned)time(NULL))); Seed n=rand()%10 - 0~9;
#include <cmath>
#include <deque>
#include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less
#include <vector>//emplace_back
//#include <math.h>
//#include <windows.h>//reverse(a,a+len);// ~ ! ~ ! floor
#include <algorithm>//sort + unique : sz=unique(b+1,b+n+1)-(b+1);+nth_element(first, nth, last, compare)
using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation
#define fo(a,b,c) for(register int a=b;a<=c;++a)
#define fr(a,b,c) for(register int a=b;a>=c;--a)
#define mem(a,b) memset(a,b,sizeof(a))
#define pr printf
#define sc scanf
#define ls rt<<1
#define rs rt<<1|1
typedef long long ll;
#define rint register int
void swapp(int &a,int &b);
double fabss(double a);
int maxx(int a,int b);
int minn(int a,int b);
int Del_bit_1(int n);
int lowbit(int n);
int abss(int a);
//const long long INF=(1LL<<60);
const double E=2.718281828;
const double PI=acos(-1.0);
const int inf=(<<);
const double ESP=1e-;
const int mod=(int)1e9+;
const int N=(int)2e6+;
void PR(int _[],int n)
{
for(int i=;i<=n;++i)
pr("%d ",_[i]);
pr("\n");
}
char s[N],s1[N],s2[N];
int a[N];
int sa[N],rk[N],s_a[N],t[N];//桶的大小要为N,因为放的是rank;
int height[N],h[N];//h是位置i的长度,heidgt是ranki的长度;
void Init(int _[],int n)
{
for(rint i=;i<=n;++i)
_[i]=;
}
bool cmp(int i,int j,int k)
{
return s_a[i]==s_a[j]&&s_a[i+k]==s_a[j+k];
}
void Sort(int len)
{
int m=;//字符集大小;
for(rint i=;i<=len;++i) ++t[a[i]],rk[i]=a[i];
for(rint i=;i<=m;++i) t[i]+=t[i-];
for(rint i=len;i>=;--i) sa[t[rk[i]]--]=i;
for(rint k=;k<=len;k<<=)
{
int cnt=;
//按第二个rank排;
for(rint i=len-k+;i<=len;++i) s_a[++cnt]=i;
for(rint i=;i<=len;++i)if(sa[i]>k) s_a[++cnt]=sa[i]-k;
//按第一个rank排;
Init(t,m);
for(rint i=;i<=len;++i) ++t[rk[s_a[i]]];
for(rint i=;i<=m;++i) t[i]+=t[i-];
for(rint i=len;i>=;--i) sa[t[rk[s_a[i]]]--]=s_a[i]; swap(rk,s_a);rk[sa[]]=cnt=;
for(rint i=;i<=len;++i)
rk[sa[i]]=cmp(sa[i],sa[i-],k)?cnt:++cnt;
if(cnt==len)break;
m=cnt;
}
//求height数组;
for(rint i=;i<=len;++i)
{
h[i]=max(,h[i-]-);
if(rk[i]==)continue;
while(a[i+h[i]]==a[sa[rk[i]-]+h[i]]) ++h[i];
}
for(rint i=;i<=len;++i) height[i]=h[sa[i]];
} int ans[N],res[N]; int main()
{
// freopen("D:\\Chrome Download\\testdata (2).in","r",stdin);
int len1,len2;
sc("%d%d",&len1,&len2);
sc("%s%s",s1+,s2+);
int len=;
for(int i=len1;i>=;--i)
a[++len]=s1[i]-'a'+;
a[++len]=;
for(int i=len2;i>=;--i)
a[++len]=s2[i]-'a'+;
Sort(len);
// PR(height,len);
// PR(sa,len);
// PR(rk,len);
int temp=;
for(int i=;i<=len;++i)
{
// temp=min(temp,height[i+1]);
if(sa[i]<=len1)
temp=height[i+];
else
ans[i]=temp,temp=min(temp,height[i+]);
}
temp=;
for(int i=len;i>=;--i)
{
// temp=min(temp,height[i+1]);
if(sa[i]<=len1)
temp=height[i];
else
ans[i]=max(ans[i],temp),temp=min(temp,height[i]);
}
// PR(ans,len);
ll Ans=;
for(int i=len;i>=len1+;--i)
{
res[i]=max(res[i+],ans[rk[i]]);
Ans+=res[i];
}
pr("%lld\n",Ans);
return ;
} /**************************************************************************************/ int maxx(int a,int b)
{
return a>b?a:b;
} void swapp(int &a,int &b)
{
a^=b^=a^=b;
} int lowbit(int n)
{
return n&(-n);
} int Del_bit_1(int n)
{
return n&(n-);
} int abss(int a)
{
return a>?a:-a;
} double fabss(double a)
{
return a>?a:-a;
} int minn(int a,int b)
{
return a<b?a:b;
}
后缀数组 LCP--模板题的更多相关文章
- PKU 2774 Long Long Message (后缀数组练习模板题)
题意:给你两个字符串.求最长公共字串的长度. by:罗穗骞模板 #include <iostream> #include <stdio.h> #include <stri ...
- poj 2774 Long Long Message 后缀数组LCP理解
题目链接 题意:给两个长度不超过1e5的字符串,问两个字符串的连续公共子串最大长度为多少? 思路:两个字符串连接之后直接后缀数组+LCP,在height中找出max同时满足一左一右即可: #inclu ...
- 后缀数组Da模板+注释 以及 dc3模板
后缀数组Da模板: 1 /* 2 后缀数组倍增法Da板子 3 */ 4 #include <cstdlib> 5 #include <cstring> 6 #include & ...
- hdu 4691 最长的共同前缀 后缀数组 +lcp+rmq
http://acm.hdu.edu.cn/showproblem.php? pid=4691 去年夏天,更多的学校的种族称号.当时,没有后缀数组 今天将是,事实上,自己的后缀阵列组合rmq或到,但是 ...
- UOJ35 后缀数组(模板)
#35. 后缀排序 这是一道模板题. 读入一个长度为 nn 的由小写英文字母组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在原串中的位置.位置编号为 1 ...
- hdu 3518 Boring counting 后缀数组LCP
题目链接 题意:给定长度为n(n <= 1000)的只含小写字母的字符串,问字符串子串不重叠出现最少两次的不同子串个数; input: aaaa ababcabb aaaaaa # output ...
- 后缀数组LCP + 二分 - UVa 11107 Life Forms
Life Forms Problem's Link Mean: 给你n个串,让你找出出现次数大于n/2的最长公共子串.如果有多个,按字典序排列输出. analyse: 经典题. 直接二分判断答案. 判 ...
- 后缀数组 + LCP加速多模式匹配算法 O(m+logn)
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> ...
- UVA 11107 Life Forms——(多字符串的最长公共子序列,后缀数组+LCP)
题意: 输入n个序列,求出一个最大长度的字符串,使得它在超过一半的DNA序列中连续出现.如果有多解,按照字典序从小到大输出所有解. 分析:这道题的关键是将多个字符串连接成一个串,方法是用不同的分隔符把 ...
随机推荐
- linux上安装nginx详细步骤
一.安装依赖包 yum install gcc gcc-c++ pcre-devel patch libffi-devel python-devel zlib-devel bzip2-devel op ...
- [python]有中文字符程序异常的解决方案
一. 含有中文字符无法运行 在python3中用的是Unicode编码,Unicode号称万国码,可以向所有的编码进行兼容.不会出现这种问题. Python2中使用的是ASCII编码,会出现这种问题. ...
- MongoDB系列二:MongoDB安装过程
一.MongoDB安装,以Linux系统安装为例:(下载:www.mongodb.org 注意使用stable版本) 1.下载最新版本的MongoDB安装包,wget http://fastdl.mo ...
- python并发——从线程池获取返回值
并发是快速处理大量相似任务的绝佳办法,但对于有返回值的方法,需要一个容器专门来存储每个进程处理完的结果 from multiprocessing import Pool import time #返回 ...
- docker crontab踩坑记录
环境,docker centos7.4 容器启动时注意两点 入口要设置/usr/sbin/init,并且配置主机完全访问权限(--privileged) (否则执行service的时候会出现Faile ...
- 20182303 2019-2020-1 《数据结构与面向对象程序设计》第2&3周学习总结
目录 教材学习内容总结 教材学习中的问题和解决过程 代码调试中的问题和解决过程 代码托管 上周考试错题总结 结对及互评 点评 学习进度条 教材学习内容总结 教材第二章内容 学习Java基本数据类型以及 ...
- ZT:在mybatis的Mapping文件写入表名 出现异常ORA-00903: 表名无效 的解决
简而言之,把#{tablename}换成${tablename}就能解决问题. 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:htt ...
- Eclipse中给SVN添加项目
SVN添加项目, 1.在svn资源库中的目标路径上右键,新建一个远程文件夹,文件夹名称和项目名称一致即可. 2,在新建的远程目录上右键,选导入,导入我们要放到svn的本地项目. 3.导入时选中项目的名 ...
- iOS开发嵌套ReactNative页面
最近使用ReactNative做项目,有信心今天目标把ReactNative框架掌握,所以自己从每个知识点学习提高自己吧...... 步骤如下: 一.创建依赖包文件(package.json): Re ...
- 【Zookeeper】分布式环境搭建
环境说明 本文以三台机器为例,分别为bigdata111,bigdata112,bigdata113三台机器,先部署bigdata111机器,然后通过scp分发配置方式配置其他两台机器: 安装步骤 上 ...