[BZOJ4566][HAOI2016]找相同子串
用SAM重新写了一遍..
我的方法比较笨,先把两个串连在一起,算出来相同子串个数,同理算出s1和s2的子串个数。作差即可。
至于如何统计子串个数,首先toposort后搞出right集的大小,然后$C_{|right|}^{2} \times (step[i]-step[fa])$就是答案。
//BZOJ 4565 //by Cydiater //2017.1.21 #include <iostream> #include <cmath> #include <cstring> #include <string> #include <queue> #include <map> #include <ctime> #include <iomanip> #include <cstdlib> #include <cstdio> #include <algorithm> #include <bitset> #include <set> #include <vector> using namespace std; #define ll long long #define up(i,j,n) for(int i=j;i<=n;i++) #define down(i,j,n) for(int i=j;i>=n;i--) #define cmax(a,b) a=max(a,b) #define cmin(a,b) a=min(a,b) #define FILE "find_2016" const int MAXN=1e6+5; const int oo=0x3f3f3f3f; char s1[MAXN],s2[MAXN],s[MAXN]; int len1,len2; struct SAM{ int now,cnt,son[MAXN][30],step[MAXN],pre[MAXN],rnk[MAXN],label[MAXN]; ll g[MAXN],ans; SAM(){now=1;cnt=1;} void Extend(int nxt){ int p=now,np=++cnt;now=np;g[np]=1; step[np]=step[p]+1; for(;p&&!son[p][nxt];p=pre[p])son[p][nxt]=np; if(!p)pre[np]=1; else{ int q=son[p][nxt],nq; if(step[q]==step[p]+1)pre[np]=q; else{ step[(nq=++cnt)]=step[p]+1; memcpy(son[nq],son[q],sizeof(son[q])); pre[nq]=pre[q]; pre[np]=pre[q]=nq; for(;son[p][nxt]==q;p=pre[p])son[p][nxt]=nq; } } } void Build(int len){ up(i,1,len)Extend(s[i]-'a'); } void Clear(){ now=cnt=1; memset(pre,0,sizeof(pre)); memset(son,0,sizeof(son)); memset(step,0,sizeof(step)); memset(g,0,sizeof(g)); memset(label,0,sizeof(label)); memset(rnk,0,sizeof(rnk)); } ll col(int len){ //topsort ans=0; up(i,1,cnt)label[step[i]]++; up(i,1,len)label[i]+=label[i-1]; up(i,1,cnt)rnk[label[step[i]]--]=i; down(i,cnt,2){ int node=rnk[i]; if(g[node]>=2) ans+=(g[node]*(g[node]-1)>>1)*(ll)(step[node]-step[pre[node]]); g[pre[node]]+=g[node]; } return ans; } }sam; namespace solution{ void Prepare(){ scanf("%s",s1+1); len1=strlen(s1+1); scanf("%s",s2+1); len2=strlen(s2+1); } void Solve(){ ll ans1,ans2,ans3; memcpy(s,s1,sizeof(s)); sam.Build(len1); ans1=sam.col(len1); sam.Clear(); memcpy(s,s2,sizeof(s)); sam.Build(len2); ans2=sam.col(len2); sam.Clear(); memcpy(s,s1,sizeof(s)); s[len1+1]='a'+26; up(i,len1+2,len1+len2+1)s[i]=s2[i-len1-1]; sam.Build(len1+len2+1); ans3=sam.col(len1+len2+1); //cout<<ans1<<' '<<ans2<<' '<<ans3<<endl; ans3-=ans1+ans2; cout<<ans3<<endl; } } int main(){ freopen(FILE".in","r",stdin); freopen(FILE".out","w",stdout); using namespace solution; Prepare(); Solve(); return 0; }
看了看别人用SAM实现的代码,发现其实不必要那样。对于s1建一个sam,统计每个点的路径对应多少个子串。然后s2串在SAM上跑,经过一个点就统计上父亲点的sum(因为变换了位置)再加上当前对应的字符串的数量就行了。
[BZOJ4566][HAOI2016]找相同子串的更多相关文章
- BZOJ4566 [Haoi2016]找相同字符【SAM】
BZOJ4566 [Haoi2016]找相同字符 给定两个字符串\(s和t\),要求找出两个字符串中所有可以相互匹配的子串对的数量 首先考虑可以怎么做,我们可以枚举\(t\)串的前缀\(t'\),然后 ...
- 字符串(后缀数组):HAOI2016 找相同子串
[HAOI2016]找相同子串 [题目描述] 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两个子串中有一个位置不同. [输入格式] 两行,两个字符 ...
- [BZOJ4566][Haoi2016]找相同字符 后缀自动机+dp
4566: [Haoi2016]找相同字符 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1212 Solved: 694[Submit][Stat ...
- [Bzoj4566][Haoi2016]找相同字符(广义后缀自动机)
4566: [Haoi2016]找相同字符 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 861 Solved: 495[Submit][Statu ...
- BZOJ4566: [Haoi2016]找相同字符
Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有一个位置不同. Input 两行,两个字符串s1,s2,长度分别 ...
- BZOJ4566 [Haoi2016]找相同字符 字符串 SAM
原文链接https://www.cnblogs.com/zhouzhendong/p/BZOJ4566.html 题目传送门 - BZOJ4566 题意 给定两个字符串 $s1$ 和 $s2$ ,问有 ...
- BZOJ4566 Haoi2016 找相同字符【广义后缀自动机】
Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有一个位置不同. Input 两行,两个字符串s1,s2,长度分别 ...
- BZOJ4566:[HAOI2016]找相同字符(SAM)
Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有一个位置不同. Input 两行,两个字符串s1,s2,长度分别 ...
- BZOJ4566 [Haoi2016]找相同字符 【后缀数组】
题目 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有一个位置不同. 输入格式 两行,两个字符串s1,s2,长度分别为n1,n2.1 & ...
随机推荐
- java中计算时间差
Calendar cale = null; SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss" ...
- Java项目使用oh-my-email发送邮件
本文使用Github开源项目oh-my-email进行测试邮件发送,并未进行更为深度的测试,如果想要快速使用,的确是一个很好的邮件发送组件.https://github.com/biezhi/oh-m ...
- 原生封装的ajax
原生封装的ajax的代码如下: //将数据转换成 a=1&b=2格式; function json2url(json){ var arr = []; //加随机数防止缓存; json.t = ...
- Sharepoint ECMAScript
前言 本文完全原创,转载请说明出处,希望对大家有用. 本篇博客是个人总结,一方面以便日后查看,另一方面希望能为其他人提供一些便利. 阅读目录 加载必要文件 (Get,Update,Delete,Add ...
- Code Forces 26C Dijkstra?
C. Dijkstra? time limit per test 1 second memory limit per test 64 megabytes input standard input ou ...
- ios开发 更改状态栏
设置statusBar 简单来说,就是设置显示电池电量.时间.网络部分标示的颜色, 这里只能设置两种颜色: 默认的黑色(UIStatusBarStyleDefault) 白色(UIStatusBarS ...
- Googlebot (Google Web search)
w推测“域名解析过程中,Google crawlers中首先是Googlebo中的Google Web search上阵”. +-----+----------------+------------- ...
- 拼团商品列表页 分析 js代码行位置对执行的影响和window.onload的原理 setTimeout传参
w TypeError : Cannot set property 'innerHTML' of nullTypeError : Cannot set property 'value' of null ...
- System.ArgumentException: 字体“Courier New”不支持样式“Regular”。
使用MongoVUE,发现报错,报错信息如下: System.ArgumentException: 字体“Courier New”不支持样式“Regular”. 说明本机字体安装不够:需安装完整的Co ...
- 20.Bulk Write Operations-官方文档摘录
1.有序操作列表将会串行执行,但如果在一个写操作过程出现异常错误,则不会处理剩余的任何写操作 2.无序操作列表将会并发执行,如果在一个写操作过程出现异常错误,则不影响,继续执行(并发无序) 3.对比无 ...