首页 > 代码库 > Bzoj4566 [Haoi2016]找相同字符
Bzoj4566 [Haoi2016]找相同字符
Submit: 378 Solved: 209
Description
给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数。两个方案不同当且仅当这两
个子串中有一个位置不同。
Input
两行,两个字符串s1,s2,长度分别为n1,n2。1 <=n1, n2<= 200000,字符串中只有小写字母
Output
输出一个整数表示答案
Sample Input
aabb
bbaa
bbaa
Sample Output
10
HINT
Source
字符串 广义后缀自动机
把两个字符串建到同一个SAM上,分别记录size。如果某个结点同时有两个串的size,那么可以更新答案
注意第23行,如果一个节点已经有了,就不新建结点了。虽然不知道为什么,但是这步似乎是必要的,不加就WA
1 /*by SilverN*/ 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 #include<vector> 8 #define LL long long 9 using namespace std;10 const int mxn=800010;11 int read(){12 int x=0,f=1;char ch=getchar();13 while(ch<‘0‘ || ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}14 while(ch>=‘0‘ && ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}15 return x*f;16 }17 struct SAM{18 int t[mxn][26],fa[mxn],l[mxn];19 int sz[mxn][2],w[mxn],rk[mxn];20 int S,cnt;21 void init(){S=cnt=1;return;}22 int add(int c,int p,int bl){23 if(t[p][c] && l[t[p][c]]==l[p]+1)return t[p][c];24 int np=++cnt;25 l[np]=l[p]+1;26 // sz[np][bl]++;27 for(;p && !t[p][c];p=fa[p])t[p][c]=np;28 if(!p)fa[np]=S;29 else{30 int q=t[p][c];31 if(l[q]==l[p]+1){fa[np]=q;}32 else{33 int nq=++cnt;l[nq]=l[p]+1;34 memcpy(t[nq],t[q],sizeof t[q]);35 fa[nq]=fa[q];36 fa[q]=fa[np]=nq;37 for(; p&& t[p][c]==q;p=fa[p])t[p][c]=nq;38 }39 }40 // printf("np:%d %d\n",np,fa[np]);41 return np;42 }43 void solve(int len){44 int i,j;45 for(i=1;i<=cnt;i++)w[l[i]]++;46 for(i=1;i<=len;i++)w[i]+=w[i-1];47 for(i=1;i<=cnt;i++)rk[w[l[i]]--]=i;48 LL ans=0;49 for(int i=cnt;i;i--){50 int t=rk[i];51 // printf("t:%d %d\n",t,fa[t]);52 sz[fa[t]][0]+=sz[t][0];53 sz[fa[t]][1]+=sz[t][1];54 }55 for(i=1;i<=cnt;i++){56 ans+=(LL)(l[i]-l[fa[i]])*sz[i][0]*sz[i][1];57 }58 printf("%lld\n",ans);59 return;60 }61 }sa;62 char s1[mxn>>1],s2[mxn>>1];63 int main(){64 int i,j;65 sa.init();66 scanf("%s%s",s1+1,s2+1);67 int n1=strlen(s1+1);68 int n2=strlen(s2+1);69 int id=sa.S;70 for(i=1;i<=n1;i++)id=sa.add(s1[i]-‘a‘,id,0),sa.sz[id][0]++;71 id=sa.S;72 for(i=1;i<=n2;i++)id=sa.add(s2[i]-‘a‘,id,1),sa.sz[id][1]++;73 sa.solve(max(n1,n2));74 return 0;75 }
Bzoj4566 [Haoi2016]找相同字符
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。