字符串(后缀数组):HAOI2016 找相同子串
[HAOI2016]找相同子串
【题目描述】
给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数。两个方案不同当且仅当这两个子串中有一个位置不同。
【输入格式】
两行,两个字符串s1,s2,长度分别为n1,n2。
【输出格式】
输出一个整数表示答案。
【样例输入】
aabb
bbaa
【样例输出】
10
【数据范围】
对于20%的数据,满足1≤n1,n2≤500;
对于40%的数据,满足1≤n1,n2≤5000;
对于100%的数据,满足1≤n1,n2≤200000,字符串中只有小写字母。
和POJ 3415几乎一样。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int N=;
char s[N];int len,d;
int r[N],Wa[N],Wb[N],sa[N],rk[N];
int Ws[N],Wv[N],lcp[N]; bool cmp(int *p,int i,int j,int l){
return p[i]==p[j]&&p[i+l]==p[j+l];
} void DA(int n,int m){
int i,j,p,*x=Wa,*y=Wb;
for(i=;i<m;i++)Ws[i]=;
for(i=;i<n;i++)++Ws[x[i]=r[i]];
for(i=;i<m;i++)Ws[i]+=Ws[i-];
for(i=n-;i>=;i--)sa[--Ws[x[i]]]=i;
for(j=,p=;p<n;j<<=,m=p){
for(p=,i=n-j;i<n;i++)y[p++]=i;
for(i=;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j;
for(i=;i<m;i++)Ws[i]=;
for(i=;i<n;i++)++Ws[Wv[i]=x[y[i]]];
for(i=;i<m;i++)Ws[i]+=Ws[i-];
for(i=n-;i>=;i--)sa[--Ws[Wv[i]]]=y[i];
for(swap(x,y),p=,x[sa[]]=,i=;i<n;i++)
x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
}
} void LCP(int n){
int i,j,k=;
for(i=;i<=n;i++)rk[sa[i]]=i;
for(i=;i<n;lcp[rk[i++]]=k)
for(k?k--:k,j=sa[rk[i]-];r[i+k]==r[j+k];k++);
} int ID(int x){x=sa[x];
if(x==d)return ;
if(x<d)return ;
return ;
} int st[N]={-},top;
long long sum[N],tot[N],ans;
int main(){
freopen("find_2016.in","r",stdin);
freopen("find_2016.out","w",stdout);
scanf("%s",s);
len=d=strlen(s);
scanf("%s",s+len+);
s[d]='#';len=strlen(s);
for(int i=;i<len;i++)r[i]=s[i];
DA(len+,);LCP(len);
for(int i=;i<=len;i++){
if(!ID(i))continue;
if(ID(i)==)ans+=tot[top];
if(i!=len){
st[++top]=lcp[i+];sum[top]=-ID(i);
tot[top]=st[top]*sum[top]+tot[top-];
while(st[top]<=st[top-]){
sum[top-]+=sum[top];
st[top-]=st[top];top--;
tot[top]=st[top]*sum[top]+tot[top-];
}
}
}
top=;
for(int i=;i<=len;i++){
if(!ID(i))continue;
if(ID(i)==)ans+=tot[top];
if(i!=len){
st[++top]=lcp[i+];sum[top]=ID(i)-;
tot[top]=st[top]*sum[top]+tot[top-];
while(st[top]<=st[top-]){
sum[top-]+=sum[top];
st[top-]=st[top];top--;
tot[top]=st[top]*sum[top]+tot[top-];
}
}
}
printf("%lld\n",ans);
return ;
}
字符串(后缀数组):HAOI2016 找相同子串的更多相关文章
- bzoj4556: [Tjoi2016&Heoi2016]字符串 (后缀数组加主席树)
题目是给出一个字符串,每次询问一个区间[a,b]中所有的子串和另一个区间[c,d]的lcp最大值,首先求出后缀数组,对于lcp的最大值肯定是rank[c]的前驱和后继,但是对于这个题会出现问题,就是题 ...
- 【BZOJ3277/3473】串/字符串 后缀数组+二分+RMQ+双指针
[BZOJ3277]串 Description 字符串是oi界常考的问题.现在给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串(注意包括本身). Inpu ...
- SPOJ 694. Distinct Substrings (后缀数组不相同的子串的个数)转
694. Distinct Substrings Problem code: DISUBSTR Given a string, we need to find the total number o ...
- Bzoj4556: [Tjoi2016&Heoi2016]字符串 后缀数组
4556: [Tjoi2016&Heoi2016]字符串 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 169 Solved: 87[Sub ...
- 【BZOJ 3473】 字符串 (后缀数组+RMQ+二分 | 广义SAM)
3473: 字符串 Description 给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串? Input 第一行两个整数n,k. 接下来n行每行一个字符串 ...
- POJ-2774-Long Long Message(后缀数组-最长公共子串)
题意: 给定两个字符串 A 和 B,求最长公共子串. 分析: 字符串的任何一个子串都是这个字符串的某个后缀的前缀. 求 A 和 B 的最长公共子串等价于求 A 的后缀和 B 的后缀的最长公共前缀的最大 ...
- BZOJ 3277: 串/ BZOJ 3473: 字符串 ( 后缀数组 + RMQ + 二分 )
CF原题(http://codeforces.com/blog/entry/4849, 204E), CF的解法是O(Nlog^2N)的..记某个字符串以第i位开头的字符串对答案的贡献f(i), 那么 ...
- BZOJ3473:字符串(后缀数组,主席树,二分,ST表)
Description 给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串? Input 第一行两个整数n,k. 接下来n行每行一个字符串. Output 一 ...
- 【BZOJ-4556】字符串 后缀数组+二分+主席树 / 后缀自动机+线段树合并+二分
4556: [Tjoi2016&Heoi2016]字符串 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 657 Solved: 274[Su ...
随机推荐
- java 内部类学习
类和内部类的关系就如同人和心脏的关系. 实例1:内部类的基本结构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 //外部 ...
- 在picture library中取某一图片的大图、小图
public static string GetPicThumbnail(SPFile file, string type) { string thumbnail = "" ...
- Spring回顾
1.IOC和DI IOC:Inversion of Control(控制反转)是一个重要的面对对象编程的法则来削减计算机程序的耦合问题,也是轻量级的Spring框架的核心. IOC理解:将组件对象的控 ...
- Win32中GDI+应用(一)
GDI+, Microsoft Graphics Device Interface Plus, 是微软在继GDI(Microsoft Graphics Device Interface)后推出的图形编 ...
- Fedora 21 设置开机启动脚本
sudo touch /etc/rc.d/rc.localsudo vim /etc/rc.d/rc.local 在/etc/rc.d/rc.local文件中写入, 然后使用:wq命令 保存并退出. ...
- SPFA_YZOI 1662: Easy sssp
题目描述 输入数据给出一个有N(2 < = N < = 1,000)个节点,M(M < = 100,000)条边的带权有向图. 要求你写一个程序, 判断这个有向图中是 ...
- 初试jQuery EasyUI
jQuery EasyUI jQuery EasyUI是一组基于jQuery的UI插件集合,而jQuery EasyUI的目标就是帮助web开发者更轻松的打造出功能丰富并且美观的UI界面.开发者不需要 ...
- Deep Belief Network
Deep Belief Network3实例3.1 测试数据按照上例数据,或者新建图片识别数据. 3.2 DBN实例//****************例2(读取固定样本:来源于经典优化算法测试函数S ...
- Hibernate报错 ** is not mapping
使用easyui+struts+hibernate 新增加一个页面功能时,总是报错,后来发现是数据库语句,不能写表名称,而是要写映射的数据库实体类名 1.struts文件修改增加action < ...
- 搬瓦工vps搭建vpn
一.下载centos6一键安装包 wget --no-check-certificate https://raw.githubusercontent.com/teddysun/across/maste ...