[题目链接]

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. I2C驱动详解

    I2C讲解: 在JZ2440开发板上,I2C是由两条数据线构成的SCL,SDA:SCL作为时钟总线,SDA作为数据总线:两条线上可挂载I2C设备,如:AT24C08 两条线连接ARM9 I2C控制器, ...

  2. ios上ZXing库的配置流程

    本文转载至 http://blog.csdn.net/louercab/article/details/26448587 步骤 首先,用Xcode创建我们的demo, 取名TestZXing(根据自己 ...

  3. 二、Android应用的界面编程(六)ProgressBar及其子类[SeekBar、RatingBar]er

    通常用于向用户显示某个耗时操作完成的百分比.Android支持几种风格的进度条,通过style属性可以为ProgressBar指定风格.该属性支持如下几个属性值. # @android:style/W ...

  4. spring 事务传播行为类型

    事务传播行为种类 Spring在TransactionDefinition接口中规定了7种类型的事务传播行为, 它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播: 事务传播行为类型 说明 P ...

  5. hdu 4068 I-number【大数】

    题目: http://acm.hdu.edu.cn/showproblem.php?pid=4608 http://acm.hust.edu.cn/vjudge/contest/view.action ...

  6. mybatis generator的用法

    1 自动生成代码 配置数据库 自动生成三个文件: 第一,java bean文件: 第二,java bean对应的dao文件,但是这里的dao只是一个接口: 第三,mybatis需要的Mapper文件: ...

  7. 如何使用Django实现用户登录验证

    最初开始搞用户登录验证的时候感觉没什么难的,不就是增删改查中的查询数据库么,但是还是遇到许多小问题,而且感觉在查询数据库的时候,要把前端的数据一条一条的进行比对,会导致我的代码很丑,而且方式很不智,所 ...

  8. Android 常用的权限

    添加WiFi以及访问网络的权限:    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE&q ...

  9. ABAP table control例子

    [转自]http://blog.csdn.net/lhx20/article/details/3039909Table control用于在screen上以表格的形式显示数据,在table contr ...

  10. iOS 8以后 定位手动授权问题

    ios8以后 都是手动授权定位权限 不过不处理这块 在ios8以后的系统就会默认永不授权 即关闭了定位权限 处理办法如下 .导入框架头文件 #import <CoreLocation/CoreL ...