后缀数组 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序列中连续出现.如果有多解,按照字典序从小到大输出所有解. 分析:这道题的关键是将多个字符串连接成一个串,方法是用不同的分隔符把 ...
随机推荐
- 进程控制块(PCB)
进程控制块PCB 我们知道,每个进程在内核中都有一个进程控制块(PCB)来维护进程相关的信息,Linux内核的进程控制块是task_struct结构体. /usr/src/linux-headers- ...
- Multiism四阶巴特沃兹低通滤波器的仿真实现
因为4阶巴特沃兹低通滤波器比较简单,所以省略设计过程和思路以及不必要的废话. 设计的滤波器的性能:截止频率大约是500HKZ,Rs = Rl = 32 欧姆. 预估滤波器大致的幅频特性曲线如下: 最初 ...
- [CSP-S2019]:赛后总结
笔者有幸参加了$CSP-S\ 2019$,$AFO$之前,写下自己最后一篇赛后总结. $Day\ 0$ 早上起来把自己调了一晚上被卡空间的题卡过了,很开心(内存限制$256MB$,然而我的内存申请是$ ...
- vue 循环Redio
标准用法,做个笔记.(图示是elementUI,其他框架大同小异) <el-radio-group @change="changePayHandler" v-model=&q ...
- 微信小程序之scroll-view的坑
好久没动小程序了,今天打算复习复习,结果刚写了一个scroll-view就遇到了一个坑,这怎么能忍,对比看文档也没发现那里出了问题,没办法只能去翻翻微信给的demo,发现scroll-view一个必要 ...
- (转载)IOCP 浅析
转自:http://www.ibm.com/developerworks/cn/java/j-lo-iocp/#author 郭 仁祥, 软件工程师, IBM 简介: 传统的 Server/Cli ...
- 关于本电脑qt5.11+vs2017+opencv3.4的配置问题
本人想用qt5.11+vs2017+opencv3.4开发程序,配置了很久才成功,现在把配置后的环境变量记录一下,以供自己以后参考,同时也供大家参考. qt5.11+vs2017+opencv3.4的 ...
- 深度学习之加载VGG19模型分类识别
主要参考博客: https://blog.csdn.net/u011046017/article/details/80672597#%E8%AE%AD%E7%BB%83%E4%BB%A3%E7%A0% ...
- SEO中常用的301永久重定向代码大全
301是永久重定向的意思,表示请求的网页已永久移动到新位置,服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置.其实301重定向在SEO中被广泛应用,也是被广泛认为比 ...
- PCL点云库(Point Cloud Library)简介
博客转载自:http://www.pclcn.org/study/shownews.php?lang=cn&id=29 什么是PCL PCL(Point Cloud Library)是在吸收了 ...