题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3998

题意概述:对于一个给定长度为N的字符串,求它的第K小子串是什么,T为0则表示不同位置的相同子串算作一个。T=1则表示不同位置的相同子串算作多个。N<=500000,K<=10^9.

应该是有三种做法的(当然后缀树我还没有看),于是就把这个东西当成后缀自动机的板子了(因为它很裸啊!!!)。

可以注意到当T=0的时候每走动一步的贡献是1,而T=1的时候每走动一步之后的贡献都是走到的这个状态的right集合大小。同时从同一个状态走出去得到的字符串又有很多种,不难想到可以搞个dp表示从这个点出发(包括这个点自己)可以找到的不同子串数(根据T而定)。

有个技巧是根据MAX把所有的状态排序之后就可以欢快地topo图上转移dp啦!(SAM的转移图是一张DAG)

所以还是好好理解一下SAM上的状态和转移吧,,,。。。。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<cctype>
using namespace std;
const int MAXN=; int T,K,n; char S[MAXN]; struct SAM{
static const int maxn=;
static const int sigma_sz=;
int pa[maxn<<],to[maxn<<][sigma_sz],mx[maxn<<],val[maxn<<]; long long cnt[maxn<<];
int sz,last,c[maxn],a[maxn<<];
SAM(){ last=sz=; memset(to[],,sizeof(to[])); }
int newnode(){
memset(to[++sz],,sizeof(to[sz]));
pa[sz]=mx[sz]=val[sz]=cnt[sz]=;
return sz;
}
void extend(int w){
int p=last,np=newnode(); last=np;
pa[np]=mx[np]=cnt[np]=;
mx[np]=mx[p]+,val[np]=;
while(p&&!to[p][w]) to[p][w]=np,p=pa[p];
if(!p) pa[np]=;
else{
int q=to[p][w];
if(mx[p]+==mx[q]) pa[np]=q;
else{
int nq=newnode(); mx[nq]=mx[p]+;
memcpy(to[nq],to[q],sizeof(to[nq]));
pa[nq]=pa[q];
pa[np]=pa[q]=nq;
while(p&&to[p][w]==q) to[p][w]=nq,p=pa[p];
}
}
}
void ready(){
for(int i=;i<=sz;i++) c[mx[i]]++;
for(int i=;i<=n;i++) c[i]+=c[i-];
for(int i=sz;i>;i--) a[c[mx[i]]--]=i;
for(int i=sz;i>;i--){
if(T) val[pa[a[i]]]+=val[a[i]];
else val[a[i]]=;
}
val[]=;
for(int i=sz;i>;i--){
cnt[a[i]]=val[a[i]];
for(int j=;j<;j++) cnt[a[i]]+=cnt[to[a[i]][j]];
}
}
void dfs(int i){
if(val[i]>=K) return;
K-=val[i];
for(int j=;j<;j++) if(to[i][j]){
if(cnt[to[i][j]]>=K){
putchar(j+'a'); dfs(to[i][j]);
return;
}
K-=cnt[to[i][j]];
}
}
}sam; void data_in()
{
gets(S);
scanf("%d%d",&T,&K);
}
void work()
{
n=strlen(S);
for(int i=;i<n;i++) sam.extend(S[i]-'a');
sam.ready();
if(sam.cnt[]<K) printf("%d\n",-);
else sam.dfs();
}
int main()
{
data_in();
work();
return ;
}

BZOJ 3998 TJOI2015 弦论 后缀自动机+DAG上的dp的更多相关文章

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

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

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

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

  3. bzoj 3998 [TJOI2015]弦论——后缀自动机

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3998 相同子串算多个的话,先求好 right ,然后求一个 sm 表示走到这个点之后有几种走 ...

  4. BZOJ 3998 [TJOI2015]弦论 ——后缀自动机

    直接构建后缀自动机. 然后. 然后只需要再后缀自动机的go树上类似二分的方法进行查找即可,实际上是“26分”. 然后遇到了处理right集合的问题,然后觉得在go和parent树上上传都是可以的,毕竟 ...

  5. BZOJ.3998.[TJOI2015]弦论(后缀自动机)

    题目链接 \(Description\) 给定字符串S,求其第K小子串.(若T=0,不同位置的相同子串算1个:否则算作多个) \(Solution\) 建SAM,处理出对于每个节点,它和它的所有后继包 ...

  6. BZOJ 3998: [TJOI2015]弦论(后缀自动机)

    传送门 解题思路 \(T=0\)时就和SP7258一样,\(T=1\)时其实也差不多,只不过要把每个点原来是\(1\)的权值改为\(Right\)集合的大小. 代码 #include<iostr ...

  7. ●BZOJ 3998 [TJOI2015]弦论

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3998题解: 后缀自动机. 当T=0时, 由于在后缀自动机上沿着trans转移,每个串都是互不 ...

  8. 【BZOJ3998】[TJOI2015]弦论 后缀自动机

    [BZOJ3998][TJOI2015]弦论 Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T ...

  9. [bzoj3998][TJOI2015]弦论-后缀自动机

    Brief Description 给定一个字符串, 您需要求出他的严格k小子串或非严格k小子串. Algorithm Design 考察使用后缀自动机. 首先原串建SAM, 然后如果考察每个状态代表 ...

随机推荐

  1. Xcode DeviceSupport

    问题:Could not locate device support files. This iPhone 6s is running iOS 12.1 (16B5059d), which may n ...

  2. Selenium处理页面---弹窗、表格、鼠标悬停、frame、下拉框、上传文件

    一.Selenium测试-常用页面处理 1.概述 UI自动化测试(GUI界面层):UI层是用户使用产品的入口,所有功能通过这一层提供给用户,测试工作大多集中在这一层,常见的测试工具有UFT.Robot ...

  3. 分组函数group by和Oracle中分析函数partition by的用法以及区别

    1.分组函数group by和Oracle中分析函数partition by的用法以及区别 2.开窗函数.

  4. Navicat for Mysql修改MySQL数据库密码,图文详解

    1.创建一个连接 2.打开连接 3.按照图示123依次点击 4.输入新密码 5.查看实现修改密码功能的SQL语句(此步骤非必须) 6.最关键的一步:点击保存 7.出现如下现象,恭喜你,修改密码成功! ...

  5. 手机浏览器页面点击不跳转(Android手机部分浏览器) 浏览器双击放大网页 解决

    手机端web网页项目(angluar js 1.4.6) 1,网页项目开发过程中,使用PC浏览器能正常访问,IOS设备浏览器也能正常访问,但是使用Android部分浏览器进行访问的时候,链接偶尔不跳转 ...

  6. .Net core NPOI导入导出Excel

    最近在想.net core NPOI 导入导出Excel,一开始感觉挺简单的,后来真的遇到很多坑.所以还是写一篇博客让其他人少走一些弯路,也方便忘记了再重温一遍.好了,多的不说,直接开始吧. 在.Ne ...

  7. Windows下远程桌面的连接

    [系统环境] 建议Windows7以上 [步骤说明] 1.使用"WIN + R"组合键打开"运行"对话框,然后输入“mstsc”,点击确定,如下图所示: 2.点 ...

  8. Delphi 过程类型

    unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...

  9. 数据分析处理库Pandas——常用操作

    DataFrame结构排序 备注:group列降序,data列升序. 合并相同项 查找相同项 添加一列,值是其他列的值进行相关操作后的值 删除列 Series结构替换值 一组值按照范围归类 归类后每类 ...

  10. Python系列5之模块

    模块 1. 模块的分类 模块,又称构件,是能够单独命名并独立地完成一定功能的程序语句的集合(即程序代码和数据结构的集合体). (1)自定义模块 自己定义的一些可以独立完成某个功能的一段程序语句,可以是 ...