BZOJ 3998: [TJOI2015]弦论【后缀自动机】

题面:

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

题目分析:

后缀自动机神奇的性质。。
不同位置的算多个,那么除了根节点每个点代表其终点集合个串。
不同位置的算一个,那么除了根节点每个路径代表一个串。
想想似乎非常的有道理

Code:

#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 1000005
#define maxc 26
using namespace std;
const int inf = 0x3f3f3f3f;
int n,T,K,sum[maxn],b[maxn],sa[maxn];
char a[maxn];
int fail[maxn]={-1},ch[maxn][maxc],len[maxn],cnt[maxn],sz,last;
void sa_extend(int c){
	int p=last,cur=++sz,q;
	len[last=cur]=len[p]+1,cnt[cur]=1;
	for(;p!=-1&&!ch[p][c];p=fail[p]) ch[p][c]=cur;
	if(p==-1) fail[cur]=0;
	else if(len[p]+1==len[q=ch[p][c]]) fail[cur]=q;
	else{
		int clone=++sz; len[clone]=len[p]+1,fail[clone]=fail[q];
		fail[q]=fail[cur]=clone;
		memcpy(ch[clone],ch[q],sizeof ch[q]);
		for(;p!=-1&&ch[p][c]==q;p=fail[p]) ch[p][c]=clone;
	}
}
int main()
{
	scanf("%s",a+1),n=strlen(a+1);
	for(int i=1;i<=n;i++) sa_extend(a[i]-'a');
	scanf("%d%d",&T,&K);
	for(int i=1;i<=sz;i++) b[len[i]]++;
	for(int i=1;i<=n;i++) b[i]+=b[i-1];
	for(int i=1;i<=sz;i++) sa[b[len[i]]--]=i;
	for(int i=sz;i>=1;i--) 
		if(T) cnt[fail[sa[i]]]+=cnt[sa[i]];
		else cnt[i]=1;
	cnt[0]=0;
	for(int i=sz,t;i>=0;i--){
		t=sa[i],sum[t]=cnt[t];
		for(int j=0;j<maxc;j++) if(ch[t][j]) sum[t]+=sum[ch[t][j]];
	}
	if(sum[0]<K) puts("-1");
	else{
		for(int p=0;K>0;K-=cnt[p])
			for(int c=0,v;c<maxc;c++){
				if(!(v=ch[p][c])) continue;
				if(sum[v]<K) K-=sum[v];
				else {putchar(c+'a'),p=v;break;}
			}
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值