这道题用后缀数组貌似会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. Hibernate5笔记4--单表查询

    单表查询:   Hibernate是DAO层技术,对数据的使用,查询是最为重要的.Hibernate的查询技术非常强大,支持原始SQL语句查询,支持QBC查询及Hibernate特有的HQL查询. H ...

  2. rollup&&cube

    group by 擴展 rollup&&cube --按job分組計算不同job的匯總工資   SELECT job, SUM (sal)     FROM emp GROUP BY ...

  3. innobackupex 相关语法讲解【转】

    innobackupex 相关语法讲解 连接服务器 The database user used to connect to the server and its password are speci ...

  4. Django中HttpRequest和HttpResponse

    请求和响应对象 Django中通过使用请求和响应对象来传递系统的状态. 当请求一个页面的时候,Django就创建一个HttpRequest对象,它包含了关于请求的元数据对象,然后Django加载适当的 ...

  5. shell用户管理->

    用户的添加与删除练习 -> 脚本1(if then) 思路:1.条件测试, 脚本使用案例, 创建用户[交互式创建] 1.怎么交互式 read -p 2.接收到对应字符串怎么创建用户 userad ...

  6. 用sklearn计算卡方检验P值

    情形: 1. 对于一批分类变量,我们通常要评价两两之间的相关程度. 2. 因变量是分类变量,衡量其他分类变量和因变量的相关性高低. 来源:https://blog.csdn.net/snowdropt ...

  7. SQLAlchemy-对象关系教程ORM-query

    一:对象关系教程查询 一个 Query创建对象时使用 Session的query()方法 .此函数接受一个变量数量的参数,可以是任何类和class-instrumented描述符的组合. Query返 ...

  8. eclipse各种报错

    1.控制台报这个错是由于tomcat的session缓存的问题; org.apache.catalina.session.StandardManager doLoad 造成原因:上次未正确关闭tomc ...

  9. python 图片上传写入磁盘功能

    本文是采取django框架,前端上传图片后端接收后写入磁盘,数据库记录图片在磁盘上的路径(相对),以下是前端上传到后端入库的基本流程 一. html代码 <!DOCTYPE html> & ...

  10. SQL SERVER 收缩数据库的命令

    --备份数据库 BACKUP DATABASE testdb TO DISK='d:\data\testdb20070906.bak' --清空日志 DUMP TRANSACTION testdb W ...