[TJOI2015]弦论(第k小子串)
题意:
对于一个给定的长度为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小子串)的更多相关文章
- 「BZOJ3998」[TJOI2015] 弦论(第K小子串)
https://www.lydsy.com/JudgeOnline/problem.php?id=3998 Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input ...
- HDU 5008 求第k小子串
本题要求第k小的distinct子串,可以根据height数组,二分出这个第k小子串所在后缀的位置信息.由于题目要求子串起始下标尽可能小.所以再在rank数组中,二分出与当前后缀LCP大于等于所求子串 ...
- SPOJ SUBLEX 求第k小子串
题目大意: 对于一个给定字符串,找到其所有不同的子串中排第k小的子串 先构建后缀自动机,然后我们可以将整个后缀自动机看做是一个DAG图,那么我们先进行拓扑排序得到 *b[N] 对于每个节点记录一个sc ...
- Lexicographical Substring Search (spoj7259) (sam(后缀自动机)+第k小子串)
Little Daniel loves to play with strings! He always finds different ways to have fun with strings! K ...
- k小子串 SPOJ - SUBLEX 2
题意: 求字典序第K大的子串 题解: 先求出后缀自动机对应节点 // 该节点后面所形成的自字符串的总数 然后直接模拟即可 #include <set> #include <map&g ...
- BZOJ 3998: [TJOI2015]弦论 后缀自动机 后缀自动机求第k小子串
http://www.lydsy.com/JudgeOnline/problem.php?id=3998 后缀自动机应用的一个模板?需要对len进行一个排序之后再统计每个出现的数量,维护的是以该字符串 ...
- BZOJ3998 弦论 【SAM】k小子串
BZOJ3998 弦论 给一个字符串,问其第\(K\)小字串是什么 两种形式 1.不同起始位置的相同串只算一次 2.不同起始位置的相同串各算一次 首先建\(SAM\) 所有串的数量就是\(SAM\)中 ...
- BZOJ 3998: [TJOI2015]弦论 [后缀自动机 DP]
3998: [TJOI2015]弦论 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2152 Solved: 716[Submit][Status] ...
- 洛谷 P3975 [TJOI2015]弦论 解题报告
P3975 [TJOI2015]弦论 题目描述 为了提高智商,ZJY开始学习弦论.这一天,她在<String theory>中看到了这样一道问题:对于一个给定的长度为\(n\)的字符串,求 ...
随机推荐
- TypeScript 命名空间
随着代码的不断增加,我们需要有组织的组合代码.TypeScript在1.x版本中提供了命名空间的方式进行代码组织,这也是TypeScript官方代码的组织方式.同时,TypeScript还实现了Jav ...
- yzoj 2377 颂芬梭哈 题解
题意 Alice 和 Mukyu 最近偶然得到了一本写有一种叫做梭哈的扑克游戏的规则的说明书(名为<C████████nd>,中间部分被涂掉了),据其所述,梭哈是一种使用黑桃.红心.梅花. ...
- Django项目配置参数大全
数据库的配置 配置文件: settings.pyDATABASES = { # 'default': { # 'ENGINE': 'django.db.backends.sqlite3', # 'NA ...
- 列主元消去法&全主元消去法——Java实现
Gauss.java package Gauss; /** * @description TODO 父类,包含高斯列主元消去法和全主元消去法的共有属性和方法 * @author PengHao * @ ...
- littleFS在RT1052移植笔记
环境:rt1052单片机+16G tf卡 为什么使用littleFS? NXP官方SDK支持! 先进的损耗平衡功能(wear leveling)可提供最长的快闪及内存寿命及最大的使用量.因为FALSH ...
- HTML5 Notification
H5的Notification特性 Web桌面通知 Notification API的通知接口用于向用户配置和显示桌面通知. 生产环境仅支持https下使用:否则会被默认禁止.开发环境可以在local ...
- CentOS7+Docker+MangoDB下部署简单的MongoDB分片集群
简单的在Docker上快速部署MongoDB分片集群 前言 文中使用的环境如下 OS:CentOS Linux release 7.5.1804 (Core) Docker:Docker versio ...
- hdu 6661 Acesrc and String Theory (后缀数组)
大意: 求重复$k$次的子串个数 枚举重复长度$i$, 把整个串分为$n/i$块, 如果每块可以$O(1)$计算, 那么最终复杂度就为$O(nlogn)$ 有个结论是: 以$j$开头的子串重复次数最大 ...
- 如何封装属于自己的WPF控件库
在网上找了一下,发现这方面的资料并不多.做传统桌面的本来就不多了吧,更别说WPF了.我可能也要另寻出路了,不过我还是觉得做桌面挺有意思的. 言归正传 首先,新建一个WPF自定义控件库项目 这里我们封 ...
- win10 总是很快自动关机 无人参与系统睡眠超时设置
解决WIN10隔几分钟就自动黑屏睡眠的方法!_Win10之家原文是卸载了电源驱动,下面是在评论里看到的方法: 这是系统无人值守时睡眠时间的设定,默认是两分钟.解决方法:1.运行注册表管理器,win+r ...