题目描述:

对于一个给定长度为N的字符串,求它的第K小子串是什么。

样例输入:

aabc
0 3

样例输出:

aab

题解:

构造后缀自动机,然后在后缀自动机上跑dfs

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath> #ifdef WIN32
#define LL "%I64d"
#else
#define LL "%lld"
#endif #ifdef CT
#define debug(...) printf(__VA_ARGS__)
#else
#define debug(...)
#endif #define R register
#define getc() (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?EOF:*S++)
#define gmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
#define gmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
#define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
#define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
char B[1<<15],*S=B,*T=B;
inline int FastIn()
{
R char ch;R int cnt=0;R bool minus=0;
while (ch=getc(),(ch < '0' || ch > '9') && ch != '-') ;
ch == '-' ?minus=1:cnt=ch-'0';
while (ch=getc(),ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
return minus?-cnt:cnt;
}
#define maxn 1000010
char str[maxn];
int a[maxn][26] , val[maxn] , fa[maxn] , l[maxn] ,last , tot , p , np , q , nq , t , k ;
int v[maxn] , que[maxn] , sum[maxn] ;
inline void extend (R int c)
{
p = last ;
np = last = ++tot ;
l[np] = l[p] + 1 ;
val[np] = 1;
for ( ; !a[p][c] && p ; ) a[p][c] = np , p = fa[p] ;
if (!p) fa[np] = 1 ;
else
{
q = a[p][c] ;
if (l[p] + 1 == l[q] ) fa[np] = q ;
else
{
nq = ++tot ;
l[nq] = l[p] + 1 ;
memcpy ( a[nq] , a[q] ,sizeof (a[q]) );
fa[nq] = fa[q] ;
fa[np] = fa[q] = nq ;
for ( ; a[p][c]==q ; ) a[p][c] = nq , p = fa[p] ;
}
}
}
inline void prepare()
{
for (R int i = 1 ; i <= tot ; i++ ) v[ l[i] ] ++ ;
for (R int i = 1 ; str[i] ; i++ ) v[i] += v[i-1] ;
for (R int i = tot ; i ; i-- ) que [ v[ l[i] ] -- ] = i ;
for (R int i = tot ; i ; i-- )
{
R int tmp = que[i];
if (t == 1) val[fa[tmp]] += val[tmp] ;
else val[tmp] = 1 ;
}
val[1] = 0 ;
for (R int i = tot ; i ; i--)
{
R int tmp = que[i] ;
sum[tmp] = val[tmp] ;
for (R int j = 0 ; j < 26 ; j++ )
sum[tmp] += sum [ a[tmp][j] ] ;
}
}
void dfs(R int x , R int k)
{
if (k <= val [x] ) return ;
k -= val[x] ;
for (R int i = 0 ; i < 26 ; i++ )
{
if (int tmp = a[x][i] )
{
if (k <= sum[tmp] )
{
printf("%c" , i + 'a' );
dfs(tmp , k);
return ;
}
k -= sum[tmp];
}
}
}
int main()
{
last = ++ tot;
scanf ( "%s\n", str + 1);
scanf( "%d %d" , &t , &k);
for (R int i = 1 ; str[i] ; i++) extend( str[i] - 'a');
prepare();
if ( sum[1] < k) puts("-1") ;
else dfs(1 , k ) ;
return 0;
}
/*
aasdfsdafsdafsadfasdfsadf
0 4
aasd
*/

【bzoj3998】[TJOI2015]弦论的更多相关文章

  1. [bzoj3998][TJOI2015]弦论_后缀自动机

    弦论 bzoj-3998 TJOI-2015 题目大意:给定一个字符串,求其$k$小子串. 注释:$1\le length \le 5\cdot 10^5$,$1\le k\le 10^9$. 想法: ...

  2. bzoj3998: [TJOI2015]弦论(SAM+dfs)

    3998: [TJOI2015]弦论 题目:传送门 题解: SAM的入门题目(很好的复习了SAM并加强Right集合的使用) 其实对于第K小的字符串直接从root开始一通DFS就好,因为son边是直接 ...

  3. BZOJ3998 TJOI2015弦论(后缀数组+二分答案)

    先看t=1的情况.显然得求出SA(因为我不会SAM).我们一位位地确定答案.设填到了第len位,二分这一位填什么之后,在已经确定的答案所在的范围(SA上的某段区间)内二分,找到最后一个小于当前串的后缀 ...

  4. bzoj3998: [TJOI2015]弦论

    SAM小裸题qwq #include <iostream> #include <cstdio> #include <cmath> #include <cstr ...

  5. bzoj3998 [TJOI2015]弦论(SAM)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3998 [题意] 询问排名第k的子串是谁,0代表相同子串不同位置算作相同,1代表相同子串 ...

  6. [bzoj3998][TJOI2015]弦论-后缀自动机

    Brief Description 给定一个字符串, 您需要求出他的严格k小子串或非严格k小子串. Algorithm Design 考察使用后缀自动机. 首先原串建SAM, 然后如果考察每个状态代表 ...

  7. 2018.12.15 bzoj3998: [TJOI2015]弦论(后缀自动机)

    传送门 后缀自动机基础题. 求第kkk小的子串(有可能要求本质不同) 直接建出samsamsam,然后给每个状态赋值之后在上面贪心选最小的(过程可以类比主席树/平衡树的查询操作)即可. 代码: #in ...

  8. BZOJ3998:[TJOI2015]弦论(SAM)

    Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个. ...

  9. BZOJ3998 TJOI2015 弦论 【后缀自动机】【贪心】

    Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个. ...

  10. BZOJ3998 [TJOI2015]弦论 【后缀自动机】

    题目 对于一个给定长度为N的字符串,求它的第K小子串是什么. 输入格式 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不同位置的相同子串算作一个.T=1则表示不同位置 ...

随机推荐

  1. 【FICO系列】SAP FICO 凭证错误:BKPFF$PRDCLN800在FI中达到的项目最大编号

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[FICO系列]SAP FICO 凭证错误:BK ...

  2. jeecg项目将workbook 的Excel流添加到zip压缩包里导出

    1.直接献出代码 Map<String,List<ConfidentialInformation>> typeMap = new HashMap<>(); try ...

  3. java中Map的put函数和get函数用法

    ---内容开始--- 没有比较完整的说明他们的用法,一般就只能看源函数,但是看起来比较的费劲. 那么究竟put函数和get函数的用法是如何的呢? 当然java中的Map集合是有Key和Value的. ...

  4. 悼念512汶川大地震遇难同胞——选拔志愿者 HDU 2188 博弈论 巴什博奕

    悼念512汶川大地震遇难同胞--选拔志愿者 HDU 2188 博弈论 巴什博奕 题意 对于四川同胞遭受的灾难,全国人民纷纷伸出援助之手,几乎每个省市都派出了大量的救援人员,这其中包括抢险救灾的武警部队 ...

  5. linux的mv、cp 命令

    用mv命令1.作用mv命令来为文件或目录改名或将文件由一个目录移入另一个目录中.该命令等同于DOS系统下的ren和move命令的组合.它的使用权限是所有用户.2.格式mv [options] 源文件或 ...

  6. Delphi XE2_XE3 Update

    Delphi 和 C++Builder XE2 更新摘要 XE2的关键特性如下: 1. FireMonkey Application Platform支持运行在Windows (32和64位),Mac ...

  7. 14-jquery元素节点操作

    **创建节点** ```var Div = $('<div>');var Div2 = $('<div>这是一个div元素</div>');``` **插入节点** ...

  8. 要了解mysql原理,还是要心里有点B树才行

      要了解数据库索引的底层原理,我们就得先了解一种叫树的数据结构,而树中很经典的一种数据结构就是二叉树!所以下面我们就从二叉树到平衡二叉树,再到B-树,最后到B+树来一步一步了解数据库索引底层的原理! ...

  9. react 错误处理

    https://www.jianshu.com/p/61d09e488743 https://codepen.io/sgroff04/pen/dVbgJy/

  10. 关于cron4j的使用

    cron4j的主要实体是调度程序.使用it.sauronsoftware.cron4j.scheduler实例,您可以在一年中的固定时间执行任务.调度程序可以每分钟执行一次任务,每五分钟执行一次,星期 ...