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. LeetCode OJ-- Merge k Sorted Lists *@

    https://oj.leetcode.com/problems/merge-k-sorted-lists/ 这道题主要是考虑测试数据的特点吧. 刚开始的时候想,每次找出头结点中最小的两个,然后取最小 ...

  2. LeetCode OJ--Word Break II ***@

    https://oj.leetcode.com/problems/word-break-ii/ class Solution { public: unordered_set<string> ...

  3. PHP生成随机码

    前几天,做了个小小的实验,生成了一组数据,数据要求是包含1000个元素,每个元素为10个随机的数字加字母的组合. 嗨呀,说写就写,然后用for循环生成了一组数据,看起来还不错,先把代码贴上来. //随 ...

  4. 网站优化—MySQL优化

    MySQL优化 简介 由于页面静态化技术可以实现对动态数据的缓存,但是有的时候还是需要去请求数据库.所以对数据库的优化也是不可缺少的. 优化思路 设计:存储引擎,字段,范式 自身:索引,自身的缓存 架 ...

  5. PHP的fsockopen方式访问接口慢的原因与优化方案

    在开发过程中常常遇到这样的需求,模拟浏览器访问某接口,并获取返回数据.我们比较常使用的方法是fsockopen与接口建立连接,然后发出指令,然后通过fgets接受返回值. 但是我们发现,通过PHP模拟 ...

  6. HTTP 代理(转)

    什么是代理服务器 Web代理(proxy)服务器是网络的中间实体. 代理位于Web客户端和Web服务器之间,扮演“中间人”的角色. HTTP的代理服务器即是Web服务器又是Web客户端. Fiddle ...

  7. Start Developing iOS Apps Today

    view types - view常见类型

  8. many-to-one多对一属性说明

    通过many-to-one元素,可以定义一种常见的与另一个持久化类的关联. 这种关系模型是多对一关联(实际上是一个对象引用-译注):这个表的一个外键引用目标表的 主键字段. <many-to-o ...

  9. spark-submit提交方式测试Demo

    写一个小小的Demo测试一下Spark提交程序的流程 Maven的pom文件 <properties> <maven.compiler.source>1.7</maven ...

  10. vue.js+koa2项目实战(一)创建项目和elementUI配置

    前端采用vuex+element-ui: 后端采用koa2+restfulAPI+sequlize: (一)项目介绍 宠物社区 1.社区 2.好友 3.说说 4.宠粮 5.健康 (二)项目框架 1.V ...