MZL's Circle Zhou

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)

Problem Description
 
MZL's Circle Zhou is good at solving some counting problems. One day, he comes up with a counting problem:
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.
 
Input
The first line of the input is a single integer T (T≤5), indicating the number of testcases. 
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.
 
Output
For each test case, output one line, a single integer indicating the answer.
 
Sample Input
2
acbcc
cccabc
bbbabbababbababbaaaabbbbabbaaaabaabbabbabbbaaabaab
abbaabbabbaaaabbbaababbabbabababaaaaabbaabbaabbaab
 
 
Sample Output
135
557539
 
题意:
  给你 两个字符串 A,B,你可以从A串中选一个子串或空, 从B串种选一个子串或空,组成一个新串
  问你能组成多少不同的新串
题解:
  麻烦的是如何去重
  考虑一个string , 我们只对分割点在最后位置的方案进行计数,这样即可避免重复计算
  首先分别对A,B进行建立后缀自动机
  预处理出对于B, 以字符X开始的不同的子串个数
  利用A进行计数,当当前A后缀自动机状态 st  nex[st][X] = NULL 时,我们将B串所有以X开始的子串加入st状态后面,更新answer

#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的更多相关文章

  1. HDU 5343 MZL's Circle Zhou

    MZL's Circle Zhou Time Limit: 1000ms Memory Limit: 131072KB This problem will be judged on HDU. Orig ...

  2. 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形成的不 ...

  3. HDU5343 MZL's Circle Zhou(SAM+记忆化搜索)

    Problem Description MZL's Circle Zhou is good at solving some counting problems. One day, he comes u ...

  4. 【bzoj3998】[TJOI2015]弦论 后缀自动机+dp

    题目描述 对于一个给定长度为N的字符串,求它的第K小子串是什么. 输入 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个.T=1则表示不同位置 ...

  5. HDU 1403 Longest Common Substring(后缀自动机——附讲解 or 后缀数组)

    Description Given two strings, you have to tell the length of the Longest Common Substring of them. ...

  6. HDU 6208 The Dominator of Strings 后缀自动机

    The Dominator of Strings Time Limit: 3000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java ...

  7. HDU - 6583 Typewriter (后缀自动机+dp)

    题目链接 题意:你要打印一段字符串,往尾部添加一个字符需要花费p元,复制一段字符到尾部需要花费q元,求打印完全部字符的最小花费. 一开始想的贪心,后来发现忘了考虑p<q的情况了,还纳闷怎么不对. ...

  8. bzoj 2806: [Ctsc2012]Cheat 后缀自动机DP

    2806: [Ctsc2012]Cheat Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 583  Solved: 330[Submit][Statu ...

  9. BZOJ4032[HEOI2015]最短不公共子串——序列自动机+后缀自动机+DP+贪心

    题目描述 在虐各种最长公共子串.子序列的题虐的不耐烦了之后,你决定反其道而行之. 一个串的“子串”指的是它的连续的一段,例如bcd是abcdef的子串,但bde不是. 一个串的“子序列”指的是它的可以 ...

随机推荐

  1. poj 3321(树状数组)

    Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 24954   Accepted: 7447 Descr ...

  2. ui设计的好网站(转载)

    设计师网址导航  http://hao.uisdc.com/ 站酷 国外: Dribbble - Show and tell for designers.Behance 这两个网站就够了啊 ————— ...

  3. CoreData: 如何预载/导入已有的数据

    原文地址:CoreData: 如何预载/导入已有的数据作者:出其东门 在系列教程一中,我们为对象建立了可视化数据模型,运行了快速肮脏测试并勾在一个表视图(table view)中来显示.而在这个教程, ...

  4. dedecms 调取当前栏目的链接和 栏目名称

    <a href="{dede:field name='typeurl' function=”GetTypeName(@me)”/}" target="_blank& ...

  5. SilverLight.3-Validation:二、银光验证。TheLabel、TheDescriptionViewer和TheValidationSummary

    ylbtech-SilverLight.3-DataControls_BetterDataFroms:二.银光验证.TheLabel.TheDescriptionViewer和TheValidatio ...

  6. Protel中的快捷键使用(网上资源)

    使用快捷键之前,将输入法切换至中文(中国)状态 Enter——选取或启动 Esc——放弃或取消 F1——启动在线帮助窗 Tab——启动浮动图件的属性窗口 Page Up——放大窗口显示比例 Page ...

  7. Windows下批处理命令启动项目bat脚本

    文件env.cfg #server name SERVER_NAME=ActivitiService #JDK Home JDK_HOME= #Main MAIN_CLASS=com.nbtv.com ...

  8. 【共享单车】—— React后台管理系统开发手记:主页面架构设计

    前言:以下内容基于React全家桶+AntD实战课程的学习实践过程记录.最终成果github地址:https://github.com/66Web/react-antd-manager,欢迎star. ...

  9. Linux下防火墙iptables用法规则详及其防火墙配置

    转:http://www.linuxidc.com/Linux/2012-08/67952.htm iptables规则 规则--顾名思义就是规矩和原则,和现实生活中的事情是一样的,国有国法,家有家规 ...

  10. Java内存区域与模拟内存区域异常

    我把Java的内存区域画了一张思维导图,以及各区域的主要功能. 模拟Java堆溢出 Java堆用于存储对象实例.仅仅要不断地创建对象而且保证GC ROOTS到对象之间有可达路径避免被回收机制清除.就能 ...