后缀数组 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序列中连续出现.如果有多解,按照字典序从小到大输出所有解. 分析:这道题的关键是将多个字符串连接成一个串,方法是用不同的分隔符把 ...
随机推荐
- docker部署项目: centos+python+redis+mysql+uwsgi+nginx
一.Centos7安装docker 1.1 环境配置 先测试是否下载了docker:查看镜像:docker images没有下载,就依次执行以下环境的安装 ①curl http://mirrors.a ...
- LoadLibrary(C:\soft\IDA 7.0\IDA 7.0\plugins\python64.dll) error: 找不到指定的模块。 C:\soft\IDA 7.0\IDA 7.0\plugins\python64.dll: can't load file LoadLibrary(C:\soft\IDA 7.0\IDA 7.0\plugins\python64.dll) erro
LoadLibrary(C:\soft\IDA 7.0\IDA 7.0\plugins\python64.dll) error: 找不到指定的模块. C:\soft\IDA 7.0\IDA 7.0\p ...
- java什么时候进行垃圾回收,垃圾回收的执行流程
java的垃圾回收分为 三个区域新生代 老年代 永久代 一个对象实例化时 先去看伊甸园有没有足够的空间如果有 不进行垃圾回收 ,对象直接在伊甸园存储.如果伊甸园内存已满,会进行一次minor gc然后 ...
- R语言:载入rjava(xlsx)包报错
先安装JRE,在电脑中添加环境变量: 电脑-右键-属性-高级系统设置-环境变量-用户变量下新建:变量名:JAVA-HOME,变量值:JRE安装路径(到jre1.8***这个文件夹就行了) 系统变量下找 ...
- sql_monitor实时监控
1 检查数据库是否启用了监控功能 1)检查参数:CONTROL_MANAGEMENT_PACK_ACCES SQL> show parameter CONTROL_MANAGEMENT_PACK ...
- article收藏
sca https://github.com/spring-cloud-incubator/spring-cloud-alibaba spring-cloud-document https://git ...
- 2.JSON.stringify()Object
JSON.stringify() JSON 通常用于与服务端交换数据. 在向服务器发送数据时一般是字符串. 我们可以使用 JSON.stringify() 方法将 JavaScript 对象转换为字符 ...
- Rose的四种视图模型
用例视图 用例视图中包括了系统中的所有参与者.用例和用例图,必要时还可以在用例视图中添加顺序图.活动图等 逻辑视图 逻辑系统关注系统是如何实现用例中所描述的功能的,主要是对系统功能性需求提供支持,即为 ...
- Understanding decimal(p, s) of sqlite3
带固定精度和小数位数的数值数据类型.decimal(p[ ,s]) 和 numeric(p[ ,s]) 固定精度和小数位数. 使用最大精度时,有效值的范围为 - 10^38 +1 到 10^38 - ...
- Swagger介绍及使用
相信无论是前端还是后端开发,都或多或少地被接口文档折磨过.前端经常抱怨后端给的接口文档与实际情况不一致.后端又觉得编写及维护接口文档会耗费不少精力,经常来不及更新.其实无论是前端调用后端,还是后端调用 ...