这道题用后缀数组貌似会T。

后缀自动机做法:

t==0:第k小的本质不同字串

  首先把后缀自动机建出来,我们会得到一个DAG,并且只存在一个点入度为0(我们称之为根),可以证明字符串的任意一个本质不同的子串(不包括空串)与该自动机上一条起点为根的长度(路径边数)大于0的路径一一对应。所以我们就可以进行DP了,dp[u]表示以u为起点的串的个数,然后有点像在BST中找第k小的思想。

t==1:第k小的普通字串(不同位置但本质相同的要区分)

  还是要dp,我yy的一个状态含义是:dp[u]表示,u节点的对应的后缀(right集合中每个位置对应一个后缀)的所有前缀的个数(空串也是前缀,并且不同位置的空串相互区分)。

这样,我们就默认一个长度为n的字符串有(n+1)*(n+2)/2个子串(包括n+1个空串)。

 /**************************************************************
Problem: 3998
User: idy002
Language: C++
Result: Accepted
Time:9736 ms
Memory:134596 kb
****************************************************************/ #include <cstdio>
#include <cstring>
#define N 1000010 typedef long long dnt; int n, k, t;
int son[N][], val[N], pnt[N], rsiz[N], ntot, last;
int idgr[N], stk[N], qu[N], bg, ed, top;
dnt dp[N];
char str[N]; void init() {
ntot = ;
pnt[] = -;
}
void append( int c ) {
int p = last;
int np = ++ntot;
val[np] = val[last]+;
while( ~p && !son[p][c] )
son[p][c]=np,p=pnt[p];
if( p==- ) {
pnt[np] = ;
} else {
int q = son[p][c];
if( val[q]==val[p]+ ) {
pnt[np] = q;
} else {
int nq = ++ntot;
memcpy( son[nq], son[q], sizeof(son[nq]) );
val[nq] = val[p]+;
rsiz[nq] = rsiz[q];
pnt[nq] = pnt[q];
pnt[q] = pnt[np] = nq;
while( ~p && son[p][c]==q ) son[p][c]=nq,p=pnt[p];
}
}
last = np;
while( ~np ) {
rsiz[np]++;
np = pnt[np];
}
}
void print() {
for( int u=; u<=ntot; u++ ) {
fprintf( stderr, "%d(dp[%d]=%lld rsiz[%d]=%d): ", u, u, dp[u], u, rsiz[u] );
for( int c=; c<; c++ ) {
int v=son[u][c];
if( !v ) continue;
fprintf( stderr, "%c,%d ", c+'a', v );
}
fprintf( stderr, "\n" );
}
}
void make_topo() {
for( int u=; u<=ntot; u++ ) {
for( int c=; c<; c++ ) {
int v=son[u][c];
if( !v ) continue;
idgr[v]++;
}
}
top = ;
for( int u=; u<=ntot; u++ )
if( idgr[u]== )
stk[++top] = u;
bg = , ed = ;
while( top ) {
int u=stk[top--];
qu[++ed] = u;
for( int c=; c<; c++ ) {
int v=son[u][c];
if( !v ) continue;
idgr[v]--;
if( idgr[v]== )
stk[++top] = v;
}
}
}
void dodp( int s ) {
make_topo();
rsiz[s] = ;
if( t== )
for( int i=; i<=ed; i++ )
rsiz[qu[i]] = ;
for( int i=ed; i>=; i-- ) {
int u=qu[i];
dp[u] = rsiz[u];
for( int c=; c<; c++ ) {
int v=son[u][c];
if( !v ) continue;
dp[u] += dp[v];
}
}
if( dp[]<k ) {
printf( "-1\n" );
return;
}
int u = ;
int kth = k;
while() {
if( kth<=rsiz[u] ) {
printf( "\n" );
return;
} else kth-=rsiz[u];
for( int c=; c<; c++ ) {
int v=son[u][c];
if( !v ) continue;
if( dp[v]>=kth ) {
u = v;
printf( "%c", c+'a' );
break;
} else {
kth -= dp[v];
}
}
}
}
int main() {
scanf( "%s", str );
scanf( "%d%d", &t, &k );
init();
for( int i=; str[i]; i++ )
append( str[i]-'a' );
dodp();
// print();
}

bzoj 2998 第k小字串的更多相关文章

  1. [bzoj P4504] K个串

    [bzoj P4504] K个串 [题目描述] 兔子们在玩k个串的游戏.首先,它们拿出了一个长度为n的数字序列,选出其中的一个连续子串,然后统计其子串中所有数字之和(注意这里重复出现的数字只被统计一次 ...

  2. bzoj : 4504: K个串 区间修改主席树

    4504: K个串 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 268  Solved: 110[Submit][Status][Discuss] ...

  3. bzoj 4504: K个串 可持久化线段树+堆

    题目: Description 兔子们在玩k个串的游戏.首先,它们拿出了一个长度为n的数字序列,选出其中的一 个连续子串,然后统计其子串中所有数字之和(注意这里重复出现的数字只被统计一次). 兔子们想 ...

  4. bzoj4504 k个串 kstring 可持久化线段树 (标记永久化)

    [fjwc2015]k个串 kstring [题目描述] 兔子们在玩k个串的游戏.首先,它们拿出了一个长度为n的数字序列,选出其中的一个连续子串,然后统计其子串中所有数字之和(注意这里重复出现的数字只 ...

  5. 数据结构(主席树):COGS 2213. K个串

    2213. K个串 ★★★★   输入文件:bzoj_4504.in   输出文件:bzoj_4504.out   简单对比时间限制:20 s   内存限制:512 MB [题目描述] 兔子们在玩k个 ...

  6. 问题 K: 周期串plus

    问题 K: 周期串plus 时间限制: 1 Sec  内存限制: 128 MB提交: 682  解决: 237[提交] [状态] [命题人:外部导入] 题目描述 如果一个字符串可以由某个长度为k的字符 ...

  7. hiho#1449 重复旋律6 求长度为k的串最大次数 后缀自动机

    题目传送门 题目大意:求长度为k的串的最大次数,把k从1到length的所有答案全部输出. 思路: 这道题放在$SAM$里就是求长度$k$对应的所有$right$集中最大的大小. 我们以$aabab$ ...

  8. 【BZOJ4504】K个串 可持久化线段树+堆

    [BZOJ4504]K个串 Description 兔子们在玩k个串的游戏.首先,它们拿出了一个长度为n的数字序列,选出其中的一个连续子串,然后统计其子串中所有数字之和(注意这里重复出现的数字只被统计 ...

  9. BZOJ 4504: K个串

    题目大意: 求一个序列的第k大的子串和. 题解: 对于一个右端点找最优的左端点,扔进堆里. 每次取堆顶,将这个右端点可以选择的左端点的区间分成两段,扔进堆里,重复k次. 现在需要对于一个固定的右端点, ...

随机推荐

  1. Red Hat Enterprise Linux 7.2下使用RPM包安装SQL Server vNext

    1.下载安装包 mssql-server:https://packages.microsoft.com/rhel/7/mssql-server/ mssql-tools:https://package ...

  2. C#里partial关键字的作用

    1. 什么是局部类型?C# 2.0 引入了局部类型的概念.局部类型允许我们将一个类.结构或接口分成几个部分,分别实现在几个不同的.cs文件中.局部类型适用于以下情况: (1) 类型特别大,不宜放在一个 ...

  3. 写在用Mac进行Java开发之前

    在用Mac进行开发之前,建议浏览以下几个概念. 1. 几个基础概念 - 计算机 计算机(computer)俗称电脑,发明者是约翰·冯·诺依曼,计算机是现代一种用于高速计算的电子计算机器,可以进行数值计 ...

  4. 洛谷P1841重要的城市

    传送门啦 重要城市有三个性质如下: 1.重要城市能对其他两个不同城市的最短路径做出贡献 2.重要城市具有唯一性,如果两不同城市之间的最短路径有两种中间城市情况,那么这两个中间城市可以彼此代替,就都不能 ...

  5. java 内部类可以被覆盖吗

    如果创建了一个内部类,然后继承其外围类并重新定义内部类时,"覆盖"内部类就好像是其外围类的一个方法,并不起作用, 这两个内部类是完全独立的两个实体,各自在自己的命名空间内 //: ...

  6. Luogu P1566 【加等式】

    看到这道题,我们首先注意到“找出其所有的加等式的个数”,自然地考虑运用计数DP求出若干数相加的和的个数 考虑将每个元素排序后DP处理若干数相加的和的个数 用f[i]表示 对于一个数a[i],对于前i- ...

  7. ubuntu和windows双系统启动顺序的修改

    ubuntu和windows双系统启动顺序的修改 说到启动就不得不说GRUB,Linux下大名鼎鼎的启动管理工具(曾经的LILO已经风光不再),当然现在已经是GRUB2了,GRUB2和GRUB最重要的 ...

  8. EXEC与sp_executesql的区别及应用

    在项目中需要将内部DECLARE的参数通过EXEC赋值后再作为下面一个EXEC参数的时候,发现都使用EXEC时,问题就不是那么简单了.趁着没有睡意研究下.EXEC的使用与缺点EXEC命令有两种用法,一 ...

  9. EFK收集Kubernetes应用日志

    本节内容: EFK介绍 安装配置EFK 配置efk-rbac.yaml文件 配置 es-controller.yaml 配置 es-service.yaml 配置 fluentd-es-ds.yaml ...

  10. Cocos2d-x for Windows Phone 用法总结

    鉴于诺基亚(微软移动这个没人用的手机)开发者比较少,cocos2dx移植方面更是少的问题,总结一下WP8移植方面的资料,希望对大家有用,自己也当作笔记留念. 1.WP8方面有两种方式创建项目,Hell ...