加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

bzoj4566【HAOI2016】找相同字符

发布时间:2020-12-13 21:11:48 所属栏目:PHP教程 来源:网络整理
导读:4566: [Haoi2016]找相同字符 Time Limit: 20 Sec Memory Limit: 256 MB Submit: 128 Solved: 75 [Submit][Status][Discuss] Description 给定两个字符串,求出在两个字符串中各取出1个子串使得这两个子串相同的方案数。两个方案不同当且仅当这两 个子串中有1

4566: [Haoi2016]找相同字符

Time Limit: 20 Sec  Memory Limit: 256 MB
Submit: 128  Solved: 75
[Submit][Status][Discuss]

Description

给定两个字符串,求出在两个字符串中各取出1个子串使得这两个子串相同的方案数。两个方案不同当且仅当这两
个子串中有1个位置不同。

Input

两行,两个字符串s1,s2,长度分别为n1,n2。1 <=n1,n2<= 200000,字符串中只有小写字母

Output

输出1个整数表示答案

Sample Input

aabb
bbaa

Sample Output

10



广义后缀自动机

建立两个串的后缀自动机,统计1下每一个节点的两个串出现次数sz[i][0]和sz[i][1],则答案等于∑(mx[i]-mx[fa[i]])*sz[i][0]*sz[i][1]。

另外1个小细节就是拓扑排序的地方要注意1下。




#include<cmath> #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #include<queue> #define F(i,j,n) for(int i=j;i<=n;i++) #define D(i,n) for(int i=j;i>=n;i--) #define ll long long #define N 200005 #define M 800005 using namespace std; int n,m,cnt=1,last; int fa[M],mx[M],c[M][26],sz[M][2],v[N],q[M]; ll ans; char a[N],b[N]; inline int read() { int x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if (ch=='-') f=⑴;ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int d[M]; queue<int> qu; void calc() { // F(i,1,cnt) v[mx[i]]++; // F(i,max(n,m)) v[i]+=v[i⑴]; // F(i,cnt) q[v[mx[i]]--]=i; //这样也是对的 int tmp=cnt; F(i,cnt) d[fa[i]]++; F(i,cnt) if (!d[i]) qu.push(i); while (!qu.empty()) { int x=qu.front();qu.pop(); q[tmp--]=x;d[fa[x]]--; if (!d[fa[x]]) qu.push(fa[x]); } D(i,cnt,1) { sz[fa[q[i]]][0]+=sz[q[i]][0]; sz[fa[q[i]]][1]+=sz[q[i]][1]; } F(i,cnt) ans+=(ll)(mx[i]-mx[fa[i]])*sz[i][0]*sz[i][1]; } void add(int x) { int p=last; if (c[p][x]&&mx[c[p][x]]==mx[p]+1){last=c[p][x];return;} int np=++cnt;last=np; mx[np]=mx[p]+1; while (p&&!c[p][x]) c[p][x]=np,p=fa[p]; if (!p) fa[np]=1; else { int q=c[p][x]; if (mx[q]==mx[p]+1) fa[np]=q; else { int nq=++cnt; mx[nq]=mx[p]+1; memcpy(c[nq],c[q],sizeof(c[q])); fa[nq]=fa[q];fa[q]=fa[np]=nq; while (p&&c[p][x]==q) c[p][x]=nq,p=fa[p]; } } } int main() { scanf("%s",a+1);scanf("%s",b+1); n=strlen(a+1);m=strlen(b+1); last=1;F(i,n) add(a[i]-'a'),sz[last][0]++; last=1;F(i,m) add(b[i]-'a'),sz[last][1]++; calc(); cout<<ans<<endl; return 0; }


(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读