HDU 5343 MZL's Circle Zhou 后缀自动机+DP
MZL's Circle Zhou
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
You are given two strings a,b which consist of only lowercase English letters. You can subtract a substring x (maybe empty) from string a and a substring y (also maybe empty) from string b, and then connect them as x+y with x at the front and y at the back. In this way, a series of new strings can be obtained.
The question is how many different new strings can be obtained in this way.
Two strings are different, if and only if they have different lengths or there exists an integer i such that the two strings have different characters at position i.
For each test case, there are two lines, the first line is string a, and the second line is string b. 1<=|a|,|b|<=90000.
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
inline long long read(){long long x=,f=;char ch=getchar();while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}return x*f;}
using namespace std; const long long INF = 1e14;
const int N = 5e5+;
const long long mod = ; struct SAM{
int isPlus[N * ],endpos[N * ];int d[N * ];
int cnt[N * ];int pos[N];
int tot,slink[*N],trans[*N][],minlen[*N],maxlen[*N],pre;
int newstate(int _maxlen,int _minlen,int* _trans,int _slink){
maxlen[++tot]=_maxlen;minlen[tot]=_minlen;
slink[tot]=_slink;
if(_trans)for(int i=;i<;i++)trans[tot][i]=_trans[i];
return tot;
}
int add_char(char ch,int u){
int c=ch-'a',v=u;
int z=newstate(maxlen[u]+,-,NULL,);
isPlus[z] = ;
while(v&&!trans[v][c]){trans[v][c]=z;d[z]+=;v=slink[v];}
if(!v){ minlen[z]=;slink[z]=;return z;}
int x=trans[v][c];
if(maxlen[v]+==maxlen[x]){slink[z]=x;minlen[z]=maxlen[x]+;return z;}
int y=newstate(maxlen[v]+,-,trans[x],slink[x]);
slink[z]=slink[x]=y;minlen[x]=minlen[z]=maxlen[y]+;
while(v&&trans[v][c]==x){trans[v][c]=y;d[x]--,d[y]++;v=slink[v];}
minlen[y]=maxlen[slink[y]]+;
return z;
}
void init_sam() {
for(int i = ; i <= tot; ++i)
for(int j = ; j < ; ++j) trans[i][j] = ;
pre = tot = ;
}
}A,B; unsigned long long f[N],dp[N];
char a[N],b[N];
int main() {
int T,cas = ;
scanf("%d",&T);
while(T--) {
scanf("%s%s",a,b);
int n = strlen(a);
int m = strlen(b);
A.init_sam();
B.init_sam();
for(int i = ; i < n; ++i) A.pre = A.add_char(a[i],A.pre);
for(int i = ; i < m; ++i) B.pre = B.add_char(b[i],B.pre); for(int i = ; i <= m; ++i) B.cnt[i] = ;
for(int i = ; i <= B.tot; ++i) B.cnt[B.maxlen[i]] += ;
for(int i = ; i <= m; ++i) B.cnt[i] += B.cnt[i-];
for(int i = B.tot; i >= ; --i) B.pos[B.cnt[B.maxlen[i]]--] = i; for(int i = ; i <= n; ++i) A.cnt[i] = ;
for(int i = ; i <= A.tot; ++i) A.cnt[A.maxlen[i]] += ;
for(int i = ; i <= n; ++i) A.cnt[i] += A.cnt[i-];
for(int i = A.tot; i >= ; --i) A.pos[A.cnt[A.maxlen[i]]--] = i;
memset(f,,sizeof(f));
memset(dp,,sizeof(dp));
for(int i = B.tot; i >= ; --i) {
int v = B.pos[i];
f[v] = ;
for(int j = ; j < ; ++j) {
if(B.trans[v][j])f[v] += f[B.trans[v][j]];
}
}
for(int i = ; i < ; ++i)
dp[i] = f[B.trans[][i]];
unsigned long long ans = ;
for(int i = A.tot; i >= ; --i) {
int v = A.pos[i];
for(int j = ; j < ; ++j) {
if(A.trans[v][j] == ) {
ans += dp[j]*(A.maxlen[v] - A.minlen[v] + );
}
}
}
for(int i = A.tot; i >= ; --i) ans += (A.maxlen[i] - A.minlen[i] + );
cout<<ans+<<endl;
}
return ;
}
HDU 5343 MZL's Circle Zhou 后缀自动机+DP的更多相关文章
- HDU 5343 MZL's Circle Zhou
MZL's Circle Zhou Time Limit: 1000ms Memory Limit: 131072KB This problem will be judged on HDU. Orig ...
- hdu 5343 MZL's Circle Zhou SAM
MZL's Circle Zhou 题意:给定两个长度不超过a,b(1 <= |a|,|b| <= 90000),x为a的连续子串,b为y的连续子串(x和y均可以是空串):问x+y形成的不 ...
- HDU5343 MZL's Circle Zhou(SAM+记忆化搜索)
Problem Description MZL's Circle Zhou is good at solving some counting problems. One day, he comes u ...
- 【bzoj3998】[TJOI2015]弦论 后缀自动机+dp
题目描述 对于一个给定长度为N的字符串,求它的第K小子串是什么. 输入 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个.T=1则表示不同位置 ...
- HDU 1403 Longest Common Substring(后缀自动机——附讲解 or 后缀数组)
Description Given two strings, you have to tell the length of the Longest Common Substring of them. ...
- HDU 6208 The Dominator of Strings 后缀自动机
The Dominator of Strings Time Limit: 3000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java ...
- HDU - 6583 Typewriter (后缀自动机+dp)
题目链接 题意:你要打印一段字符串,往尾部添加一个字符需要花费p元,复制一段字符到尾部需要花费q元,求打印完全部字符的最小花费. 一开始想的贪心,后来发现忘了考虑p<q的情况了,还纳闷怎么不对. ...
- bzoj 2806: [Ctsc2012]Cheat 后缀自动机DP
2806: [Ctsc2012]Cheat Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 583 Solved: 330[Submit][Statu ...
- BZOJ4032[HEOI2015]最短不公共子串——序列自动机+后缀自动机+DP+贪心
题目描述 在虐各种最长公共子串.子序列的题虐的不耐烦了之后,你决定反其道而行之. 一个串的“子串”指的是它的连续的一段,例如bcd是abcdef的子串,但bde不是. 一个串的“子序列”指的是它的可以 ...
随机推荐
- hdu 2739(尺取法)
Sum of Consecutive Prime Numbers Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 22876 ...
- Oracle 查看表存储内存
--分配表的物理存储1 select segment_name, bytes from user_segments where segment_type = 'TABLE'; From User_Ex ...
- (1)jquery基本用法
引入jquery 本地引用 <script src="jquery-3.2.1.js"></script> 网络引用 谷歌CDN <script sr ...
- fetch API 简单解读
http://f2e.souche.com/blog/fetch-api-jie-du/?utm_source=tuicool&utm_medium=referral 在我们日常的前端开发中, ...
- Java开发笔记(一百零四)普通线程池的运用
前面介绍了线程的基本用法,以及多线程并发的问题处理,但实际开发中往往存在许多性质相似的任务,比如批量发送消息.批量下载文件.批量进行交易等等.这些同类任务的处理流程一致,不存在资源共享问题,相互之间也 ...
- Tmux常用快捷键及命令
Exported from workflowy! tmux session start/create session- tmux- tmux new-session -s portage listin ...
- 苹果iOS APP配置HTTPS,iOS ATS配置SSL,苹果ATS标准解决方案
参考沃通:
- 【jsp】jsp访问到之后报错如下:Uncaught SyntaxError: Unexpected token <
jsp访问到之后报错如下: Uncaught SyntaxError: Unexpected token < 问题出在哪里: 发现把这个注销掉,就不会出现这个问题了,那script引用js文件哪 ...
- 【java】java处理随机浮点数(小数点后两位)用RMB的大写数值规则输出
晚上上床前,拿到这个有意思的问题,就想玩弄一番: =========================================================================== ...
- 修改Centos默认源
原文:http://mirrors.aliyun.com/help/centos?spm=5176.bbsr150321.0.0.d6ykiD 1.备份 mv /etc/yum.repos.d/Cen ...