bzoj4566【HAOI2016】找相同字符
2016-06-29 00:10
239 查看
4566: [Haoi2016]找相同字符
Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 128 Solved: 75
[Submit][Status][Discuss]
Description
给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数。两个方案不同当且仅当这两个子串中有一个位置不同。
Input
两行,两个字符串s1,s2,长度分别为n1,n2。1 <=n1, n2<= 200000,字符串中只有小写字母Output
输出一个整数表示答案Sample Input
aabbbbaa
Sample Output
10广义后缀自动机
建立两个串的后缀自动机,统计一下每个节点的两个串出现次数sz[i][0]和sz[i][1],则答案等于∑(mx[i]-mx[fa[i]])*sz[i][0]*sz[i][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,j,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 ,q[M]; ll ans; char a ,b ; inline int read() { int x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if (ch=='-') f=-1;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,1,max(n,m)) v[i]+=v[i-1]; // F(i,1,cnt) q[v[mx[i]]--]=i; //这样也是对的 int tmp=cnt; F(i,1,cnt) d[fa[i]]++; F(i,1,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,1,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,1,n) add(a[i]-'a'),sz[last][0]++; last=1;F(i,1,m) add(b[i]-'a'),sz[last][1]++; calc(); cout<<ans<<endl; return 0; }
相关文章推荐
- Nodejs基础中间件Connect
- JavaScript强化教程——jQuery选择器
- 5类系统推荐算法,告诉你用户需要什么
- 如何在Ubuntu14.04服务器上安装NodeJS
- Javascript.Reactjs-5-prop-validation-and-proptypes
- nginx启动、重启、关闭
- 搜索
- Node线上部署管理器PM2
- iOS---如何在CocoaPods上发布自己的项目
- 量化-使用python计算各类移动平均线
- 什么才算是真正的编程能力?
- 4 种开源云安全工具
- 图片
- $q 实例分析 Angular 中的 Promise
- 微小说|那个傻子不傻了
- 微信公众平台开发之语音识别.Net代码解析
- .Net微信开发之如何解决access_token过期问题
- 微信公众平台开发之处理图片.Net代码解析
- Python通过RabbitMQ服务器实现交换机功能的实例教程
- Python操作RabbitMQ服务器实现消息队列的路由功能