[Codeforces 452E] Three Strings
[题目链接]
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的更多相关文章
- Codeforces 452E Three Strings(后缀自动机)
上学期很认真地学了一些字符串的常用工具,各种 suffix structre,但是其实对后缀自动机这个部分是理解地不太透彻的,以致于看了师兄A这题的代码后,我完全看不懂,于是乎重新看回一些学习后缀自动 ...
- Codeforces 452E Three strings 字符串 SAM
原文链接https://www.cnblogs.com/zhouzhendong/p/CF542E.html 题目传送门 - CF452E 题意 给定三个字符串 $s1,s2,s3$ ,对于所有 $L ...
- Codeforces 868D Huge Strings - 位运算 - 暴力
You are given n strings s1, s2, ..., sn consisting of characters 0 and 1. m operations are performed ...
- codeforces 112APetya and Strings(字符串水题)
A. Petya and Strings 点击打开题目 time limit per test 2 seconds memory limit per test 256 megabytes input ...
- [Codeforces Round #438][Codeforces 868D. Huge Strings]
题目链接:868D - Huge Strings 题目大意:有\(n\)个字符串,\(m\)次操作,每次操作把两个字符串拼在一起,并询问这个新串的价值.定义一个新串的价值\(k\)为:最大的\(k\) ...
- [Educational Round 5][Codeforces 616F. Expensive Strings]
这题调得我心疲力竭...Educational Round 5就过一段时间再发了_(:з」∠)_ 先后找了三份AC代码对拍,结果有两份都会在某些数据上出点问题...这场的数据有点水啊_(:з」∠)_[ ...
- Codeforces 559B - Equivalent Strings
559B - Equivalent Strings 思路:字符串处理,分治 不要用substr(),会超时 AC代码: #include<bits/stdc++.h> #include&l ...
- Codeforces 112A-Petya and Strings(实现)
A. Petya and Strings time limit per test 2 seconds memory limit per test 256 megabytes input standar ...
- CodeForces - 985F Isomorphic Strings
假如两个区间的26的字母出现的位置集合分别是 A1,B1,A2,B2,....., 我们再能找到一个排列p[] 使得 A[i] = B[p[i]] ,那么就可以成功映射了. 显然集合可以直接hash, ...
随机推荐
- 树莓派 CPU & 主板 温度
CPU cat /sys/class/thermal/thermal_zone0/temp | awk '{print $1/1000}' 主板 /opt/vc/bin/vcgencmd measur ...
- 现在有一张半径为r的圆桌,其中心位于(x,y),现在他想把圆桌的中心移到(x1,y1)。每次移动一步,都必须在圆桌边缘固定一个点然后将圆桌绕这个点旋转。问最少需要移动几步。
// ConsoleApplication5.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<vector> ...
- hibernate的一级缓存和二级缓存详解
hibernate为我们提供了一级缓存和二级缓存,目的是为了减少应用程序对数据库的访问次数. 一级缓存: (1)所谓一级缓存就是session级别的缓存,当我们使用他的范围是当前的session,当s ...
- nginx配置1:借助Nginx搭建反向代理服务器与缓存静态文件
修改配置文件nginx.conf (1)进程数与每个进程的最大连接数: •nginx进程数,建议设置为等于CPU总核心数 •单个进程最大连接数,那么该服务器的最大连接数=连接数*进程数 (2)Ngin ...
- Android 开发小工具之:Tools 属性 (转)
Android 开发小工具之:Tools 属性 http://blog.chengyunfeng.com/?p=755#ixzz4apLZhfmi 今天来介绍一些 Android 开发过程中比较有用但 ...
- 【JavaSE】Java问题总结
使用BufferedInputStream时OutOfMemoryError异常 eclipse Luna安装subversion(SVN) 使用BufferedInputStream时OutOfMe ...
- 网卡配置bond
在实际的生产环境中,服务器都需要配置bond环境的,以提高安全性及均衡能力.我公司网卡配置的是mode=1 类型,mode=1 是主备模式,当其中一块网卡不能工作时,另一块网卡立即代替.以下是mode ...
- EasyNVR无插件流媒体服务器前端技术防止重复提交的方法
现在随着接触EasyNVR时间越来越长,越发的觉得EasyNVR真的是一个"神器".从功能上来说自身不仅可以拉出来使用(具体功能搜索EasyNVR一定有惊喜!),也可以作为设备端与 ...
- EasyNVR H5无插件摄像机直播解决方案前端解析之:如何在播放界面添加实时云台控制界面
如何在播放器上加一个云台控制界面 问题: 对于实时直播的视频播放, 由于播放页面客观样式要求(一个播放器占据了整个页面),因此很难找出很合理的空间来放置其他功能按钮的位置(比如配合实时是平的云台控制界 ...
- Mybatis之Mapper动态代理
一.什么是Mapper的动态代理 采用Mapper动态代理方法只需要编写相应的Mapper接口(相当于Dao接口),那么Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同Dao接 ...