[题目链接]

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

[算法]

首先构建广义后缀自动机

对于自动机上的每个节点 , 维护一棵平衡树存储所有它所匹配的字符串编号

可以通过启发式合并得到

计算答案时 , 我们枚举每个右端点 , 当当前集合大小 < K时 , 不断走向link节点

时间复杂度 : 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 = 2e5 + ;
const int ALPHA = ;
#define rint register int int n , k;
string st[N]; struct Suffix_Automaton
{
int sz , last;
int father[N] , depth[N] , child[N][ALPHA] , cnt[N];
set< int > s[N];
vector< int > a[N];
Suffix_Automaton()
{
sz = ;
last = ;
}
inline int new_node(int dep)
{
depth[++sz] = dep;
father[sz] = ;
memset(child[sz] , , sizeof(child[sz]));
return sz;
}
inline void extend(int ch , int col)
{
int np = child[last][ch];
if (np)
{
if (depth[np] == depth[last] + )
{
s[np].insert(col);
last = np;
return;
} else
{
int nq = new_node(depth[last] + );
father[nq] = father[np];
father[np] = nq;
memcpy(child[nq] , child[np] , sizeof(child[nq]));
for (int p = last; child[p][ch] == np; p = father[p])
child[p][ch] = nq;
s[nq].insert(col);
last = nq;
return;
}
} else
{
np = new_node(depth[last] + );
int p = last;
for (; child[p][ch] == ; p = father[p])
child[p][ch] = np;
if (child[p][ch] == np)
{
father[np] = ;
s[np].insert(col);
last = np;
return;
} else
{
int q = child[p][ch];
if (depth[q] == depth[p] + )
{
father[np] = q;
s[np].insert(col);
last = np;
return;
} else
{
int nq = new_node(depth[p] + );
father[nq] = father[q];
father[np] = father[q] = nq;
memcpy(child[nq] , child[q] , sizeof(child[nq]));
for (; child[p][ch] == q; p = father[p])
child[p][ch] = nq;
s[np].insert(col);
last = np;
}
}
}
}
inline void insert(string s , int col)
{
last = ;
for (rint i = ; i < (int)s.size(); ++i)
extend(s[i] - 'a' , col);
}
inline void dfs(int u)
{
for (unsigned i = ; i < a[u].size(); ++i)
{
int v = a[u][i];
dfs(v);
if ((int)s[u].size() < (int)s[v].size())
swap(s[u] , s[v]);
for (set< int > :: iterator it = s[v].begin(); it != s[v].end(); ++it)
s[u].insert(*it);
}
cnt[u] = (int)s[u].size();
}
inline void work()
{
for (rint i = ; i <= sz; ++i)
a[father[i]].push_back(i);
dfs();
}
} SAM; 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 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;
} int main()
{ read(n); read(k);
for (rint i = ; i <= n; ++i)
{
cin >> st[i];
SAM.insert(st[i] , i);
}
SAM.work();
for (rint i = ; i <= n; ++i)
{
int now = ;
ll ans = ;
for (rint j = ; j < st[i].size(); ++j)
{
now = SAM.child[now][st[i][j] - 'a'];
while (now != && SAM.cnt[now] < k) now = SAM.father[now];
ans += (ll)SAM.depth[now];
}
printf("%lld " , ans);
}
printf("\n"); return ; }

[Codeforces 204E] Little Elephant and Strings的更多相关文章

  1. codeforces 204E. Little Elephant and Strings(广义后缀自动机,Parent树)

    传送门在这里. 大意: 给一堆字符串,询问每个字符串有多少子串在所有字符串中出现K次以上. 解题思路: 这种子串问题一定要见后缀自动机Parent树Dfs序统计出现次数都是套路了吧. 这道题统计子串个 ...

  2. 字符串(后缀自动机):Codeforces Round #129 (Div. 1) E.Little Elephant and Strings

    E. Little Elephant and Strings time limit per test 3 seconds memory limit per test 256 megabytes inp ...

  3. CodeForces - 204C Little Elephant and Furik and Rubik

    CodeForces - 204C Little Elephant and Furik and Rubik 个人感觉是很好的一道题 这道题乍一看我们无从下手,那我们就先想想怎么打暴力 暴力还不简单?枚 ...

  4. CodeForces-204E:Little Elephant and Strings (广义后缀自动机求出现次数)

    The Little Elephant loves strings very much. He has an array a from n strings, consisting of lowerca ...

  5. Codeforces D. Little Elephant and Interval(思维找规律数位dp)

    题目描述: Little Elephant and Interval time limit per test 2 seconds memory limit per test 256 megabytes ...

  6. 【Codeforces 204E】Little Elephant and Strings

    Codeforces 204 E 题意:给\(n\)个串,求对于每一个串在至少\(k\)个串中出现的它的子串\(S_{l..r}\)有多少个. 思路:后缀自动机上\(dp\)... 我们首先构造出这\ ...

  7. Codeforces Round #129 (Div. 1)E. Little Elephant and Strings

    题意:有n个串,询问每个串有多少子串在n个串中出现了至少k次. 题解:sam,每个节点开一个set维护该节点的字符串有哪几个串,启发式合并set,然后在sam上走一遍该串,对于每个可行的串,所有的fa ...

  8. CodeForces 259A Little Elephant and Chess

     Little Elephant and Chess Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d &am ...

  9. Educational Codeforces Round 12 C. Simple Strings 贪心

    C. Simple Strings 题目连接: http://www.codeforces.com/contest/665/problem/C Description zscoder loves si ...

随机推荐

  1. iOS CLLocationManager定位

    本文转载至 http://www.tuicool.com/articles/7JBRZn 在iOS8以前的版本中,我们使用CLLocationManager定位是没有问题的,最近在iOS8系统中却无法 ...

  2. Python 基本数据类型和序列类型

    python 3.6.4 中,有9种数据类型: int, float, bool, complex, list, tuple, string, set, dict (1).int 整型,不可变 (2) ...

  3. Manager模块 队列 管道 进程池

    Manager模块 作用:  多进程共享变量. Manager的字典类型: 如果value是简单类型,比如int,可以直接赋值给共享变量,并可以后续直接修改 如果value是复杂类型 ,比如list, ...

  4. Spring框架结构

    在processOn思维导图上看的一个程序员写的,挺不错的,分享出来,便于学习和回顾.

  5. 洛谷P1038 神经网络==codevs1088 神经网络

    P1038 神经网络 题目背景 人工神经网络(Artificial Neural Network)是一种新兴的具有自我学习能力的计算系统,在模式识别.函数逼近及贷款风险评估等诸多领域有广泛的应用.对神 ...

  6. 九度OJ 1209:最小邮票数 (遍历)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2252 解决:741 题目描述: 有若干张邮票,要求从中选取最少的邮票张数凑成一个给定的总值.     如,有1分,3分,3分,3分,4分五 ...

  7. iOS-事件传递和响应机制

    转自:http://www.jianshu.com/p/2e074db792ba 前言: 按照时间顺序,事件的生命周期是这样的: 事件的产生和传递(事件如何从父控件传递到子控件并寻找到最合适的view ...

  8. Django 路飞学成书写规范的总结

    路飞学成书写规范的总结 命名 项目/文件/函数 -> 小写+下划线 类 驼峰式 路由 将每个功能的路由进行分割, 或者做上注释 类和方法的注释 每个类都要注释是干什么的 每个方法也要进行注释标明 ...

  9. 为什么Git 比 SVN 好

    原文链接:http://www.worldhello.net/2012/04/12/why-git-is-better-than-svn.html Why Git is better than SVN ...

  10. Unity3D C#事件管理:EventManager

    原文地址:http://bbs.9ria.com/thread-153258-1-1.html 原project地址:https://github.com/djandrew/UnityEventMan ...