题意:

对于一个给定的长度为n的字符串,求出它的第k小子串。

有参数t,t为0则表示不同位置的相同子串算作一个,t为1则表示不同位置的相同子串算作多个。

题解:

首先,因为t的原因,后缀数组较难实现,这里不讨论。

使用后缀自动机:

因为,这里需要按字典序考虑子串,所以要使用trs指针。

首先,计算出每个子串的贡献:t=0则为1,t=1则为出现次数。

然后,通过记搜算出匹配到每个点之后可以形成多少贡献。因为使用trs,无需考虑压缩。

最后,在每个节点处找到唯一一个应当向下计算的点,循环直到找到解。

代码:

#include <stdio.h>
#define ll long long
int trs[1000010][26],fa[1000010],len[1000010],sl=1,la=1;
int su[1000010];ll dp[1000010];
void insert(int c)
{
int np=++sl,p=la;
len[np]=len[la]+1;la=np;
while(p!=0&&trs[p][c]==0)
{
trs[p][c]=np;
p=fa[p];
}
if(p==0)
fa[np]=1;
else
{
int q=trs[p][c];
if(len[q]==len[p]+1)
fa[np]=q;
else
{
int nq=++sl;
len[nq]=len[p]+1;
fa[nq]=fa[q];fa[q]=fa[np]=nq;
for(int i=0;i<26;i++)
trs[nq][i]=trs[q][i];
while(p!=0&&trs[p][c]==q)
{
trs[p][c]=nq;
p=fa[p];
}
}
}
su[la]=1;
}
int fr[1000010],ne[1000010],v[1000010],bs=0;
void addb(int a,int b)
{
v[bs]=b;
ne[bs]=fr[a];
fr[a]=bs++;
}
void build()
{
for(int i=1;i<=sl;i++)
fr[i]=-1;
for(int i=2;i<=sl;i++)
addb(fa[i],i);
}
void dfs0(int u)
{
for(int i=fr[u];i!=-1;i=ne[i])
{
dfs0(v[i]);
su[u]|=su[v[i]];
}
}
void dfs1(int u)
{
for(int i=fr[u];i!=-1;i=ne[i])
{
dfs1(v[i]);
su[u]+=su[v[i]];
}
}
void dfs2(int u)
{
if(dp[u])
return;
dp[u]=su[u];
for(int i=0;i<26;i++)
{
if(trs[u][i])
{
dfs2(trs[u][i]);
dp[u]+=dp[trs[u][i]];
}
}
}
char zf[500010];
int main()
{
int t,k,u=1;
scanf("%s%d%d",zf,&t,&k);
for(int i=0;zf[i]!=0;i++)
insert(zf[i]-'a');
build();
if(t==0)dfs0(1);
else dfs1(1);
dfs2(1);
if(dp[1]-su[1]<k)
{
printf("-1");
return 0;
}
while(1)
{
if(u!=1)
{
if(su[u]>=k)
break;
k-=su[u];
}
int i;
for(i=0;i<26;i++)
{
if(trs[u][i]==0)
continue;
if(dp[trs[u][i]]>=k)
break;
k-=dp[trs[u][i]];
}
printf("%c",i+'a');
u=trs[u][i];
}
return 0;
}

[TJOI2015]弦论(第k小子串)的更多相关文章

  1. 「BZOJ3998」[TJOI2015] 弦论(第K小子串)

    https://www.lydsy.com/JudgeOnline/problem.php?id=3998 Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input ...

  2. HDU 5008 求第k小子串

    本题要求第k小的distinct子串,可以根据height数组,二分出这个第k小子串所在后缀的位置信息.由于题目要求子串起始下标尽可能小.所以再在rank数组中,二分出与当前后缀LCP大于等于所求子串 ...

  3. SPOJ SUBLEX 求第k小子串

    题目大意: 对于一个给定字符串,找到其所有不同的子串中排第k小的子串 先构建后缀自动机,然后我们可以将整个后缀自动机看做是一个DAG图,那么我们先进行拓扑排序得到 *b[N] 对于每个节点记录一个sc ...

  4. Lexicographical Substring Search (spoj7259) (sam(后缀自动机)+第k小子串)

    Little Daniel loves to play with strings! He always finds different ways to have fun with strings! K ...

  5. k小子串 SPOJ - SUBLEX 2

    题意: 求字典序第K大的子串 题解: 先求出后缀自动机对应节点 // 该节点后面所形成的自字符串的总数 然后直接模拟即可 #include <set> #include <map&g ...

  6. BZOJ 3998: [TJOI2015]弦论 后缀自动机 后缀自动机求第k小子串

    http://www.lydsy.com/JudgeOnline/problem.php?id=3998 后缀自动机应用的一个模板?需要对len进行一个排序之后再统计每个出现的数量,维护的是以该字符串 ...

  7. BZOJ3998 弦论 【SAM】k小子串

    BZOJ3998 弦论 给一个字符串,问其第\(K\)小字串是什么 两种形式 1.不同起始位置的相同串只算一次 2.不同起始位置的相同串各算一次 首先建\(SAM\) 所有串的数量就是\(SAM\)中 ...

  8. BZOJ 3998: [TJOI2015]弦论 [后缀自动机 DP]

    3998: [TJOI2015]弦论 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2152  Solved: 716[Submit][Status] ...

  9. 洛谷 P3975 [TJOI2015]弦论 解题报告

    P3975 [TJOI2015]弦论 题目描述 为了提高智商,ZJY开始学习弦论.这一天,她在<String theory>中看到了这样一道问题:对于一个给定的长度为\(n\)的字符串,求 ...

随机推荐

  1. TypeScript 命名空间

    随着代码的不断增加,我们需要有组织的组合代码.TypeScript在1.x版本中提供了命名空间的方式进行代码组织,这也是TypeScript官方代码的组织方式.同时,TypeScript还实现了Jav ...

  2. yzoj 2377 颂芬梭哈 题解

    题意 Alice 和 Mukyu 最近偶然得到了一本写有一种叫做梭哈的扑克游戏的规则的说明书(名为<C████████nd>,中间部分被涂掉了),据其所述,梭哈是一种使用黑桃.红心.梅花. ...

  3. Django项目配置参数大全

    数据库的配置 配置文件: settings.pyDATABASES = { # 'default': { # 'ENGINE': 'django.db.backends.sqlite3', # 'NA ...

  4. 列主元消去法&全主元消去法——Java实现

    Gauss.java package Gauss; /** * @description TODO 父类,包含高斯列主元消去法和全主元消去法的共有属性和方法 * @author PengHao * @ ...

  5. littleFS在RT1052移植笔记

    环境:rt1052单片机+16G tf卡 为什么使用littleFS? NXP官方SDK支持! 先进的损耗平衡功能(wear leveling)可提供最长的快闪及内存寿命及最大的使用量.因为FALSH ...

  6. HTML5 Notification

    H5的Notification特性 Web桌面通知 Notification API的通知接口用于向用户配置和显示桌面通知. 生产环境仅支持https下使用:否则会被默认禁止.开发环境可以在local ...

  7. CentOS7+Docker+MangoDB下部署简单的MongoDB分片集群

    简单的在Docker上快速部署MongoDB分片集群 前言 文中使用的环境如下 OS:CentOS Linux release 7.5.1804 (Core) Docker:Docker versio ...

  8. hdu 6661 Acesrc and String Theory (后缀数组)

    大意: 求重复$k$次的子串个数 枚举重复长度$i$, 把整个串分为$n/i$块, 如果每块可以$O(1)$计算, 那么最终复杂度就为$O(nlogn)$ 有个结论是: 以$j$开头的子串重复次数最大 ...

  9. 如何封装属于自己的WPF控件库

    在网上找了一下,发现这方面的资料并不多.做传统桌面的本来就不多了吧,更别说WPF了.我可能也要另寻出路了,不过我还是觉得做桌面挺有意思的. 言归正传  首先,新建一个WPF自定义控件库项目 这里我们封 ...

  10. win10 总是很快自动关机 无人参与系统睡眠超时设置

    解决WIN10隔几分钟就自动黑屏睡眠的方法!_Win10之家原文是卸载了电源驱动,下面是在评论里看到的方法: 这是系统无人值守时睡眠时间的设定,默认是两分钟.解决方法:1.运行注册表管理器,win+r ...