BZOJ4566: [Haoi2016]找相同字符
2016-06-01 16:39
330 查看
Description
给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数。两个方案不同当且仅当这两个子串中有一个位置不同。
Input
两行,两个字符串s1,s2,长度分别为n1,n2。1 <=n1, n2<= 200000,字符串中只有小写字母Output
输出一个整数表示答案Sample Input
aabbbbaa
Sample Output
10裸题,用SAM来做的话先建出第一个串的后缀自动机,把第二个串拿上去运行,不完整节点直接计算,完整节点打个懒标记最后扫一遍就行了。
#include<cstdio> #include<cctype> #include<queue> #include<cstring> #include<algorithm> #define rep(i,s,t) for(int i=s;i<=t;i++) #define dwn(i,s,t) for(int i=s;i>=t;i--) #define ren for(int i=first[x];i;i=next[i]) using namespace std; typedef long long ll; const int maxn=400010; int to[maxn][26],l[maxn],fa[maxn],last=1,cnt=1; int f[maxn],siz[maxn],od[maxn],c[maxn]; void extend(int c) { int p,q,np,nq;p=last;l[last=np=++cnt]=l[p]+1;siz[np]=1; for(;!to[p][c];p=fa[p]) to[p][c]=np; if(!p) fa[np]=1; else { q=to[p][c]; if(l[p]+1==l[q]) fa[np]=q; else { l[nq=++cnt]=l[p]+1; fa[nq]=fa[q];fa[q]=fa[np]=nq; memcpy(to[nq],to[q],sizeof(to[nq])); for(;to[p][c]==q;p=fa[p]) to[p][c]=nq; } } } char s[maxn]; int main() { scanf("%s",s); for(int i=0;s[i];i++) extend(s[i]-'a'); scanf("%s",s); int p=1,len=0;ll ans=0; rep(i,1,cnt) c[l[i]]++; rep(i,1,cnt) c[i]+=c[i-1]; dwn(i,cnt,1) od[c[l[i]]--]=i; dwn(i,cnt,1) siz[fa[od[i]]]+=siz[od[i]]; for(int i=0;s[i];i++) { int c=s[i]-'a'; if(to[p][c]) len++,p=to[p][c]; else { while(p&&!to[p][c]) p=fa[p]; if(p) len=l[p]+1,p=to[p][c]; else p=1,len=0; } ans+=(ll)siz[p]*(len-l[fa[p]]);f[fa[p]]++; } dwn(i,cnt,1) { int x=od[i];f[fa[x]]+=f[x]; ans+=(ll)f[x]*siz[x]*(l[x]-l[fa[x]]); } printf("%lld\n",ans); return 0; }
相关文章推荐
- C#操作XML的方法
- SQL Server索引 (原理、存储)聚集索引、非聚集索引、堆 <第一篇>
- 10037---Java NIO系列教程(七) FileChannel
- nginx 禁止ip直接访问web服务器
- 属性动画之ObjectAnimator
- 解读膳食指南(4)-2016版儿童平衡膳食算盘
- 用SecureCRT上传文件到服务器
- SpringDataJpa的Specification查询
- jquery 实现滚动条下拉时无限加载的简单实例
- Ionic项目中使用极光推送-android
- 第三方登录
- AMD规范
- Struts2对于BigDecimal类型的转换问题
- Java Service Wrapper3-Wrapper配置详解及高级应用
- 详解Android进程和线程
- Android软键盘的隐藏与显示
- 知识图谱基本知识
- CPU核心温度获取
- StringUtils检查字符串是否空或是null
- 数据库视频总结