[题目链接]

https://codeforces.com/contest/452/problem/E

[算法]

构建后缀数组

用并查集合并答案即可

时间复杂度 : O(NlogN)

[代码]

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const int N = 3e5 + ;
const int P = 1e9 + ; #define rint register int struct info
{
int id , ht;
} a[N]; int n;
int height[N] , sa[N] , rk[N] , sz[N] , cnta[N] , cntb[N] , cntc[N] , bel[N] , fa[N];
ll ans[N];
char s[N] , s1[N] , s2[N] , s3[N]; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void add(T &x , T y)
{
x += y;
while (x >= P) x -= P;
}
template <typename T> inline void read(T &x)
{
T f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
}
inline void build_sa()
{
static int x[N] , y[N] , cnt[N];
for (rint i = ; i <= n; ++i) ++cnt[s[i]];
for (rint i = ; i <= ; ++i) cnt[i] += cnt[i - ];
for (rint i = n; i >= ; --i) sa[cnt[s[i]]--] = i;
rk[sa[]] = ;
for (rint i = ; i <= n; ++i) rk[sa[i]] = rk[sa[i - ]] + (s[sa[i]] != s[sa[i - ]]);
for (rint k = ; rk[sa[n]] != n; k <<= )
{
for (rint i = ; i <= n; ++i)
x[i] = rk[i] , y[i] = (i + k <= n) ? rk[i + k] : ;
for (rint i = ; i <= n; ++i) cnt[i] = ;
for (rint i = ; i <= n; ++i) ++cnt[y[i]];
for (rint i = ; i <= n; ++i) cnt[i] += cnt[i - ];
for (rint i = n; i >= ; i--) rk[cnt[y[i]]--] = i;
for (rint i = ; i <= n; ++i) cnt[i] = ;
for (rint i = ; i <= n; ++i) ++cnt[x[i]];
for (rint i = ; i <= n; ++i) cnt[i] += cnt[i - ];
for (rint i = n; i >= ; i--) sa[cnt[x[rk[i]]]--] = rk[i];
rk[sa[]] = ;
for (rint i = ; i <= n; ++i) rk[sa[i]] = rk[sa[i - ]] + (x[sa[i]] != x[sa[i - ]] || y[sa[i]] != y[sa[i - ]]);
}
}
inline void get_height()
{
int k = ;
for (rint i = ; i <= n; ++i)
{
if (k) --k;
int j = sa[rk[i] + ];
while (s[i + k] == s[j + k]) ++k;
height[rk[i]] = k;
}
}
inline bool cmp(info a , info b)
{
return a.ht > b.ht;
}
inline int get_root(int x)
{
if (fa[x] == x) return x;
else return fa[x] = get_root(fa[x]);
}
inline void merge(int x , int y)
{
if (sz[x] > sz[y]) swap(x , y);
fa[x] = y;
cnta[y] += cnta[x];
cntb[y] += cntb[x];
cntc[y] += cntc[x];
sz[y] += sz[x];
return;
}
inline int _min(int x , int y , int z)
{
return min(min(x , y) , z);
} int main()
{ scanf("%s%s%s" , s1 + , s2 + , s3 + );
int l1 = strlen(s1 + ) , l2 = strlen(s2 + ) , l3 = strlen(s3 + );
for (rint i = ; i <= l1; ++i)
{
s[++n] = s1[i];
bel[n] = ;
}
s[++n] = '#';
for (rint i = ; i <= l2; ++i)
{
s[++n] = s2[i];
bel[n] = ;
}
s[++n] = '@';
for (rint i = ; i <= l3; ++i)
{
s[++n] = s3[i];
bel[n] = ;
}
build_sa();
get_height();
for (rint i = ; i < n; ++i)
{
a[i].id = i;
a[i].ht = height[i];
}
sort(a + , a + n , cmp);
for (rint i = ; i <= n; ++i)
{
fa[i] = i;
sz[i] = ;
if (bel[sa[i]] == ) cnta[i] = ;
if (bel[sa[i]] == ) cntb[i] = ;
if (bel[sa[i]] == ) cntc[i] = ;
}
for (rint i = ; i < n; ++i)
{
int rk = a[i].id , ht = a[i].ht;
if (!ht) break;
int fx = get_root(rk) , fy = get_root(rk + );
add(ans[ht] , 1LL * cnta[fx] * cntb[fx] % P * cntc[fy] % P);
add(ans[ht] , 1LL * cnta[fx] * cntc[fx] % P * cntb[fy] % P);
add(ans[ht] , 1LL * cntb[fx] * cntc[fx] % P * cnta[fy] % P);
add(ans[ht] , 1LL * cnta[fy] * cntb[fy] % P * cntc[fx] % P);
add(ans[ht] , 1LL * cnta[fy] * cntc[fy] % P * cntb[fx] % P);
add(ans[ht] , 1LL * cntb[fy] * cntc[fy] % P * cnta[fx] % P);
merge(fx , fy);
}
for (rint i = n; i >= ; --i) add(ans[i] , ans[i + ]);
for (rint i = ; i <= _min(l1 , l2 , l3); ++i) printf("%lld " , ans[i]);
printf("\n"); return ; }

[Codeforces 452E] Three Strings的更多相关文章

  1. Codeforces 452E Three Strings(后缀自动机)

    上学期很认真地学了一些字符串的常用工具,各种 suffix structre,但是其实对后缀自动机这个部分是理解地不太透彻的,以致于看了师兄A这题的代码后,我完全看不懂,于是乎重新看回一些学习后缀自动 ...

  2. Codeforces 452E Three strings 字符串 SAM

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF542E.html 题目传送门 - CF452E 题意 给定三个字符串 $s1,s2,s3$ ,对于所有 $L ...

  3. Codeforces 868D Huge Strings - 位运算 - 暴力

    You are given n strings s1, s2, ..., sn consisting of characters 0 and 1. m operations are performed ...

  4. codeforces 112APetya and Strings(字符串水题)

    A. Petya and Strings 点击打开题目 time limit per test 2 seconds memory limit per test 256 megabytes input ...

  5. [Codeforces Round #438][Codeforces 868D. Huge Strings]

    题目链接:868D - Huge Strings 题目大意:有\(n\)个字符串,\(m\)次操作,每次操作把两个字符串拼在一起,并询问这个新串的价值.定义一个新串的价值\(k\)为:最大的\(k\) ...

  6. [Educational Round 5][Codeforces 616F. Expensive Strings]

    这题调得我心疲力竭...Educational Round 5就过一段时间再发了_(:з」∠)_ 先后找了三份AC代码对拍,结果有两份都会在某些数据上出点问题...这场的数据有点水啊_(:з」∠)_[ ...

  7. Codeforces 559B - Equivalent Strings

    559B - Equivalent Strings 思路:字符串处理,分治 不要用substr(),会超时 AC代码: #include<bits/stdc++.h> #include&l ...

  8. Codeforces 112A-Petya and Strings(实现)

    A. Petya and Strings time limit per test 2 seconds memory limit per test 256 megabytes input standar ...

  9. CodeForces - 985F Isomorphic Strings

    假如两个区间的26的字母出现的位置集合分别是 A1,B1,A2,B2,....., 我们再能找到一个排列p[] 使得 A[i] = B[p[i]] ,那么就可以成功映射了. 显然集合可以直接hash, ...

随机推荐

  1. Nginx https免费SSL证书配置指南

    生成证书 $ cd /usr/local/nginx/conf $ openssl genrsa -des3 -out server.key 1024 $ openssl req -new -key  ...

  2. rootkit基础

    应用程序总是离不开系统内核所提供的服务,比如它要使用内存的时候,只要跟操作系统申请就行了,而不用自己操心哪里有空闲的内存空间等问题,实际上,这些问题是由操作系统的内核来代劳的.站在黑客的角度讲,如果能 ...

  3. linux下安装redis报错问题。

    1.使用tar -xzvf redis-2.4.5.tar.gz来解压安装包 2.使用make命令来编译Redis 如果出现错误需要查看是否缺少gcc gcc-c++ zmalloc.h:50:31: ...

  4. OS开发之旅之App的生命周期【转载】

    原文链接 http://www.360doc.com/content/15/0918/14/27799428_499912639.shtml 在iOS App中,入口函数并不在根目录下,而是在“Sup ...

  5. oracle 误删数据的回复操作

    update operator t set t.username = (select username from operator  AS OF TIMESTAMP TO_TIMESTAMP('201 ...

  6. 简单理解ThreadLocal原理和适用场景

    https://blog.csdn.net/qq_36632687/article/details/79551828?utm_source=blogkpcl2 参考文章: 正确理解ThreadLoca ...

  7. arcgis10.0 切片并发布服务及验证

    1.切片参考网址:https://jingyan.baidu.com/article/fa4125accc6bef28ac7092d7.html 2.通过下面代码验证  参考网址https://www ...

  8. 基于Apache POI 向xlsx写入数据

    [0]写在前面 0.1) these codes are from 基于Apache POI 的向xlsx写入数据 0.2) this idea is from http://cwind.iteye. ...

  9. C++刷题——2736: 指针练习--输出最大值

    Description 採用指针法,输出10个整型数中的最大值和最小值 Input 10个整数 Output 最大值和最小值 Sample Input 2 6 3 8 1 5 7 0 4 9 Samp ...

  10. python 基础 1.5 python 数据类型(一)--整型 浮点型 布尔型及字符串和常用方法

    一.python 数据类型:数值,字符串,列表,元组,字典.以下操作是在linux 下 ipython中进行 1.数值 1>123  与  “123”的区别 答:123为数值,“123”在pyt ...