3998: [TJOI2015]弦论

【题目描述】

传送门

【题解】

先用SAM算出不同子串个数,然后二分查找就可以了(像平衡树一样的查找第K小方式)

【代码如下】

#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN=5e5+5;
int n,TT,K,Sum[MAXN<<1],Hsh[MAXN<<1],Sa[MAXN<<1];char ch[MAXN];
struct SAM{int cnt,lst,Son[MAXN<<1][27],Len[MAXN<<1],Siz[MAXN<<1],Fa[MAXN<<1];SAM(){cnt=lst=1;}void Insert(int c){int fa=lst,p=++cnt;lst=cnt;Len[p]=Len[fa]+1;Siz[p]=1;for(;fa&&!Son[fa][c];fa=Fa[fa]) Son[fa][c]=p;if(!fa){Fa[p]=1;return;}int x=Son[fa][c];if(Len[fa]+1==Len[x]){Fa[p]=x;return;}int y=++cnt;Fa[y]=Fa[x],Fa[x]=Fa[p]=y;Len[y]=Len[fa]+1;for(int i=0;i<26;++i) Son[y][i]=Son[x][i];for(;fa&&Son[fa][c]==x;fa=Fa[fa]) Son[fa][c]=y;}
}T;
void DFS(int x,int k){if(k<=T.Siz[x]) return;k-=T.Siz[x];for(int j=0;j<26;++j)if(k<=Sum[T.Son[x][j]]){putchar(j+'a'),DFS(T.Son[x][j],k);break;}else k-=Sum[T.Son[x][j]];
}
int main(){scanf("%s",ch+1);n=strlen(ch+1);for(int i=1;i<=n;++i) T.Insert(ch[i]-'a');scanf("%d%d",&TT,&K);for(int i=1;i<=T.cnt;++i) ++Hsh[T.Len[i]];for(int i=1;i<=n;++i) Hsh[i]+=Hsh[i-1];for(int i=1;i<=T.cnt;++i) Sa[Hsh[T.Len[i]]--]=i;for(int i=T.cnt,p;p=Sa[i],i;--i) TT?T.Siz[T.Fa[p]]+=T.Siz[p]:T.Siz[p]=1;T.Siz[1]=0;for(int i=T.cnt,p;i;--i){Sum[p=Sa[i]]=T.Siz[p];for(int j=0;j<26;j++) Sum[p]+=Sum[T.Son[p][j]];}if(K>Sum[1]) return printf("-1\n"),0;return DFS(1,K),0;
}

转载于:https://www.cnblogs.com/XSamsara/p/10547918.html

BZOJ3998: [TJOI2015]弦论【SAM】相关推荐

  1. [BZOJ3998][TJOI2015]弦论

    [BZOJ3998][TJOI2015]弦论 试题描述 对于一个给定长度为N的字符串,求它的第K小子串是什么. 输入 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T和K,T为0则表示不 ...

  2. luogu P3975 [TJOI2015]弦论 SAM

    luogu P3975 [TJOI2015]弦论 链接 bzoj 思路 建出sam. 子串算多个的,统计preant tree的子树大小,否则就是大小为1 然后再统计sam的节点能走到多少串. 然后就 ...

  3. BZOJ3998 TJOI2015弦论(后缀数组+二分答案)

    先看t=1的情况.显然得求出SA(因为我不会SAM).我们一位位地确定答案.设填到了第len位,二分这一位填什么之后,在已经确定的答案所在的范围(SA上的某段区间)内二分,找到最后一个小于当前串的后缀 ...

  4. Bzoj3998: [TJOI2015]弦论

    题面 传送门 Sol \(sam\) 求一个串的不重复的第\(k\)小子串很好办 如果可以相同 那么要算上每个点(前缀)的后缀的个数 那么就是这个\(endpos(right)\)集合的子串的出现次数 ...

  5. BZOJ3998: [TJOI2015]弦论(后缀自动机,Parent树)

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

  6. bzoj3998 [TJOI2015]弦论

    后缀自动机 我们建出后缀自动机,对于每个节点我们算出他和他的后继结点一共可以形成多少个不同的串,不同根据t来定义 这里我们不需要考虑每个节点代表的那些等价类字符串,因为那些字符串不同的前缀在到达这个节 ...

  7. bzoj3998/洛谷3975 [TJOI2015]弦论 (后缀自动机)

    bzoj3998/洛谷3975 [TJOI2015]弦论 题意:求第 k 小字串 方法:先建立SAM,和上一题一样按照拓扑序求出size(表示这个串出现的次数).这道题我们需要求第 k 小,所以我们还 ...

  8. P3975 [TJOI2015]弦论 (SAM)

    [TJOI2015]弦论 - 洛谷 感觉位置不同算相同还是比较好想的,我们top排序后算每个点后面连接了多少点就知道里面有多少字串了,然后求k大就行了: 考了位置不同算不同的话,我们就要考虑endpo ...

  9. 洛谷_3975 [TJOI2015]弦论(后缀自动机)

    [TJOI2015]弦论 题目链接:https://www.luogu.com.cn/problem/P3975 题解: 对于T==0,只需要构造自动机,将每个状态节点的cnt设为1,然后DFS即可. ...

  10. 【后缀自动机】Luogu P3975 [TJOI2015]弦论题解

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

最新文章

  1. 4. 编程规范和编程安全指南--go语言
  2. 智源研究院发布 2020 年世界十大 AI 进展
  3. Processing Orders With Windows Workflow
  4. 成功解决SQL Server软件中出现的18456问题
  5. jQuery easyUI--zTree属性菜单
  6. 网页交互动画终极指南
  7. Java易混小知识——equals方法和==的区别
  8. hadoop 二次开发DatanodeWriteTimeout设置
  9. Java描述设计模式(06):建造者模式
  10. iTextSharp 使用详解用C#制作PDF文件全攻略
  11. 计算机网络网际协议实验报告,计算机网络课程网际协议IP地址实验报告.doc
  12. 【PyQt5 知识点示例代码】布局、菜单、信号与槽、对话框、组件
  13. ThinkPHP3.2.3 的异常和错误屏蔽处理
  14. C++11新特性——auto和decltype
  15. 腾讯云买服务器密码,腾讯云服务器初始密码是什么?
  16. 什么是网站CDN?原理是什么?
  17. 每月的第一个工作日执行的corn表达式
  18. 优秀博士生和普通博士生差距能有多大?
  19. 腾讯6W月薪架构师能力曝光!微信架构为什么是史上最值钱的IM架构?
  20. 2020 全国大学生数学建模竞赛C题思路+代码

热门文章

  1. 二叉树的创建及遍历--java实现
  2. 【前端基础进阶】JS原型、原型链、对象详解
  3. 709. To Lower Case
  4. Apache目录禁止解析
  5. Java容器类研究8:HashMap
  6. Intent与intent-filter
  7. 3、grep,vim,压缩功能详解
  8. [报告]HDU 4343 Interval query
  9. 关于SOA的应用研究思考
  10. Java ClassLoader基础及加载不同依赖 Jar 中的公共类