弦论 bzoj-3998 TJOI-2015

题目大意:给定一个字符串,求其$k$小子串。

注释:$1\le length \le 5\cdot 10^5$,$1\le k\le 10^9$。


想法

后缀数组傻逼题。

初学后缀自动机我们尝试用后缀自动机解决。

首先先建出$SAM$。

分别考虑$T=0$和$T=1$的情况。

我们处理$f$数组表示以当前节点代表的字符串为前缀的子串个数。

它们俩之间的区别就是$Right$集合的大小。

详情看代码把。

代码

#include <bits/stdc++.h>
#define N 1000010
using namespace std;
int n,opt,nxt[N][26],fa[N],dis[N],lst=1,cnt=1,v[N],q[N],Right[N],f[N];
char str[N];
void update(int c)
{
int p=lst,np=lst=++cnt;
dis[np]=dis[p]+1; Right[np]=1;
while(p&&!nxt[p][c]) nxt[p][c]=np,p=fa[p];
if(!p) fa[np]=1;
else
{
int q=nxt[p][c];
if(dis[q]==dis[p]+1) fa[np]=q;
else
{
int nq=++cnt;
memcpy(nxt[nq],nxt[q],sizeof nxt[q]);
dis[nq]=dis[p]+1; fa[nq]=fa[q]; fa[np]=fa[q]=nq;
while(p&&nxt[p][c]==q) nxt[p][c]=nq,p=fa[p];
}
}
}
void init()
{
for(int i=1;i<=cnt;i++) v[dis[i]]++;
for(int i=1;i<=n;i++) v[i]+=v[i-1];
for(int i=cnt;i;i--) q[v[dis[i]]--]=i;
for(int i=cnt;i;i--)
{
int t=q[i];
if(opt) Right[fa[t]]+=Right[t];
else Right[t]=1;
}
Right[1]=0; for(int i=cnt;i;i--)
{
int t=q[i]; f[t]=Right[t];
for(int j=0;j<26;j++) f[t]+=f[nxt[t][j]];
}
}
void query(int p,int k)
{
if(k<=Right[p]) return;
k-=Right[p];
for(int i=0;i<26;i++) if(nxt[p][i])
{
if(k<=f[nxt[p][i]])
{
putchar(i+'a'); query(nxt[p][i],k);
return;
}
k-=f[nxt[p][i]];
}
}
int main()
{
int k; scanf("%s%d%d",str+1,&opt,&k); n=strlen(str+1);
for(int i=1;i<=n;i++) update(str[i]-'a');
init();
if(k>f[1]) puts("-1");
else query(1,k);
return 0;
}

小结:后缀自动机搭配其他的数据结构的时候会比较有用,但是感觉后缀数组更好写啊$qwq$......

[bzoj3998][TJOI2015]弦论_后缀自动机的更多相关文章

  1. BZOJ_3998_[TJOI2015]弦论_后缀自动机

    BZOJ_3998_[TJOI2015]弦论_后缀自动机 Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行 ...

  2. 2018.12.15 bzoj3998: [TJOI2015]弦论(后缀自动机)

    传送门 后缀自动机基础题. 求第kkk小的子串(有可能要求本质不同) 直接建出samsamsam,然后给每个状态赋值之后在上面贪心选最小的(过程可以类比主席树/平衡树的查询操作)即可. 代码: #in ...

  3. BZOJ3998 TJOI2015 弦论 【后缀自动机】【贪心】

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

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

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

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

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

  6. BZOJ3998 TJOI2015弦论(后缀自动机)

    先考虑相同子串视为一个.按SAM的拓扑序预处理出从每个节点开始能得到多少个本质不同子串(注意虽然一个节点对应多个子串,但到达该点时当前的子串显然是确定为其中一个的),然后按位贪心即可. 相同子串视为多 ...

  7. 【BZOJ3998】弦论(后缀自动机)

    [BZOJ3998]弦论(后缀自动机) 题面 BZOJ 题解 这题应该很简单 构建出\(SAM\)后 求出每个点往后还能构建出几个串 按照拓扑序\(dp\)一些就好了 然后就是第\(k\)大,随便搞一 ...

  8. [TJOI2015]弦论(后缀自动机)

    传送门 题意: 对给定字符串\(s\),求其第\(k\)小子串,重复串被计入以及不被计入这两种情况都需考虑. 思路: 首先构建后缀自动机,之后就考虑在后缀自动机上\(dp\). 我们知道如果要考虑重复 ...

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

    题目链接 建出后缀自动机. T=0,每个子串算一次,否则每个子串算该子串的\(endpos\)集合大小次. 用\(f[i]\)表示结点\(i\)表示的\(endpos\)集合大小,则\(f[i]\)为 ...

随机推荐

  1. 关于maven source1.5报错

    是因为maven 默认是1.5编译的 <build>//加上这个配置,把编译给改掉试试 <pluginManagement> <plugins> <plugi ...

  2. win7系统 windows update 总是更新失败解决方法:

    win7系统 windows update 总是更新失败解决方法: 右键单击桌面“计算机”选择“管理“. 进到“计算机管理“窗口后,展开”服务和应用程序“并双击”服务“,在窗口右侧按照名称找到”Win ...

  3. PHP一句话后门过狗姿势万千之传输层加工

    既然木马已就绪,那么想要利用木马,必然有一个数据传输的过程,数据提交是必须的,数据返回一般也会有的,除非执行特殊命令. 当我们用普通菜刀连接后门时,数据时如何提交的,狗狗又是如何识别的,下面结合一个实 ...

  4. (转)编码剖析Spring管理Bean的原理

    http://blog.csdn.net/yerenyuan_pku/article/details/52832434 在Spring的第一个案例中,我们已经知道了怎么将bean交给Spring容器进 ...

  5. elasticsearch时间格式DateFormat的含义

    时间格式 枚举(或者英文)format pattern 含义 custom - 自定义属性 none - 不转化 basic_date yyyyMMdd 基本时间 basic_date_time   ...

  6. SVM-支持向量机 学习 1

    参考 https://zhuanlan.zhihu.com/p/42334376 https://blog.csdn.net/liugan528/article/details/79448379 ht ...

  7. 屏幕卫士模式系统APP开发

    利用php的socket编程来直接给接口发送数据来模拟post的操作,(黎灿:I8O..2853..296O 可电可V)线上线下和物流结合在一起,才会产生新零售. 2016年阿里云栖大会上,阿里巴巴马 ...

  8. django 127.0.0.1 将您重定向的次数过多

    "GET /?next=/%3Fnext%3D/%253Fnext%253D/ HTTP/1.1" 302 0 solution reference from django.con ...

  9. 剑指Offer整理笔记

    说在前面,本篇的目的是为了学习剑指offer,以及博客园的排版功能,并将文章排版得整洁得体. 梵蒂冈梵蒂冈地方官方

  10. 洛谷 P1518 两只塔姆沃斯牛

    P1518 两只塔姆沃斯牛 The Tamworth Two 简单的模拟题,代码量不大. 他们走的路线取决于障碍物,可以把边界也看成障碍物,遇到就转,枚举次,因为100 * 100 * 4,只有4个可 ...