3998: [TJOI2015]弦论

题目:传送门


题解:

   SAM的入门题目(很好的复习了SAM并加强Right集合的使用)

   其实对于第K小的字符串直接从root开始一通DFS就好,因为son边是直接根据字符存的呀,相当于自带字典序,直接从‘a' 开始找。

   一开始初始化一下从当前状态出发所能走的路径数(也就是能构成多少个字符串啦)

   然后根据T= 0/1分情况来处理Right集合大小:

   T== 0 :那Right集合大小就直接全部等于1咯

   T== 1  : 直接累加啊(原始操作)

   然后具体看代码注释吧:

  


代码:

 #include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
struct SAM
{
int son[],fail,dep;
}ch[];int cnt,last,root,a[];
void add(int k)
{
int x=a[k];
int p=last,np=++cnt;ch[np].dep=k;
while(p && ch[p].son[x]==)ch[p].son[x]=np,p=ch[p].fail;
if(p==)ch[np].fail=root;
else
{
int q=ch[p].son[x];
if(ch[p].dep+==ch[q].dep)ch[np].fail=q;
else
{
int nq=++cnt;
ch[nq]=ch[q];ch[nq].dep=ch[p].dep+;
ch[np].fail=ch[q].fail=nq;
while(p && ch[p].son[x]==q)ch[p].son[x]=nq,p=ch[p].fail;
}
}
last=np;
}
int len,T,k,Rsort[],r[],sa[],sum[];
char s[];
void dfs(int x)
{
if(k<=r[x])return ;
k-=r[x];//要从x继续往下搜,那么结束位置为x的子串一定会更优,那就减去这样的子串个数啊,r记录的就是这个
for(int i=;i<=;i++)
if(ch[x].son[i]!=)
{
int y=ch[x].son[i];
if(k>sum[y])k-=sum[y];//当前k如果比y可以走出来的路径还要多,那么第k小的一定不在y的路径上。由于是按照字典序小到大问的,那么y的路径一定比后面枚举的要优,那也要减,sum记录的就是可行路径数
else {printf("%c",i+'a');dfs(y);return ;}
}
}
int main()
{
cnt=;root=last=++cnt;
scanf("%s",s+);len=strlen(s+);
for(int i=;i<=len;i++)a[i]=s[i]-'a';
for(int i=;i<=len;i++)add(i);
scanf("%d%d",&T,&k);
for(int i=;i<=cnt;i++)Rsort[ch[i].dep]++;
for(int i=;i<=len;i++)Rsort[i]+=Rsort[i-];
for(int i=cnt;i>=;i--)sa[Rsort[ch[i].dep]--]=i;
for(int i=,p=root;i<=len;i++)p=ch[p].son[a[i]],r[p]++;
for(int i=cnt;i>=;i--)
if(T==)r[ch[sa[i]].fail]=;
else r[ch[sa[i]].fail]+=r[sa[i]];
r[root]=;
for(int i=cnt;i>=;i--)
{
int now=sa[i];sum[now]=r[now];
for(int j=;j<=;j++)if(ch[now].son[j]!=)sum[now]+=sum[ch[now].son[j]];
}
if(k>sum[root])printf("-1\n");
else dfs(root);
return ;
}

bzoj3998: [TJOI2015]弦论(SAM+dfs)的更多相关文章

  1. BZOJ3998:[TJOI2015]弦论(SAM)

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

  2. [bzoj3998][TJOI2015]弦论_后缀自动机

    弦论 bzoj-3998 TJOI-2015 题目大意:给定一个字符串,求其$k$小子串. 注释:$1\le length \le 5\cdot 10^5$,$1\le k\le 10^9$. 想法: ...

  3. 【BZOJ 3998】 3998: [TJOI2015]弦论 (SAM )

    3998: [TJOI2015]弦论 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2627  Solved: 881 Description 对于一 ...

  4. luogu P3975 [TJOI2015]弦论 SAM

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

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

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

  6. bzoj3998 [TJOI2015]弦论(SAM)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3998 [题意] 询问排名第k的子串是谁,0代表相同子串不同位置算作相同,1代表相同子串 ...

  7. 【BZOJ3998】弦论 [SAM]

    弦论 Time Limit: 10 Sec  Memory Limit: 256 MB[Submit][Status][Discuss] Description 对于一个给定长度为N的字符串,求它的第 ...

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

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

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

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

随机推荐

  1. guice 整合ninja framework(七)

    ninja是一个优秀的,轻量级的mvc框架,它与google guice整合比较好.下面看一下例子: 我们在web.xml 配置一下: <listener> <listener-cl ...

  2. Three学习之曲线

    曲线 属性 1. .arcLengthDivisions 当通过.getLengths计算曲线的累积段长度时,此值决定了分割的数量.为了确保在使用.getSpacedPoint等方法时的精度,如果曲线 ...

  3. adb 通过 WiFi 连接 Android 设备

    PC 和 Android 设备连接在同一个局域网. 查看 Android 设备的 IP:设置 > WLAN > 选择连接的WiFi > 查看IP地址. PC 端执行: ping &l ...

  4. Ajax内容签名技术(减少无谓流量损耗)

    UI界面Ajax获取数据内容的时候,一般是直接加载内容填充,不管内容有无变化.自己也是一直这么干,包括定时刷新公告等.今天在浏览器控制台调试的时候,发现动态刷新内容,其实挺耗费流量的,特别是内容无变化 ...

  5. Python学习笔记基础篇-(1)Python周边

    一.系统命令 1.Ctrl+D 退出Python IDLE input方法中输入EOF字符,键入Ctrl+D 2.命令行选项: -d   提供调试输出 -O 生成优化的字节码(.pyo文件) -S 不 ...

  6. mach-o格式分析

    0x00 摘要 人生无根蒂,飘如陌上尘. 分散逐风转,此已非常身. — 陶渊明 <杂诗> mach-o格式是OS X系统上的可执行文件格式,类似于windows的PE与linux的ELF, ...

  7. CDR中是否有图层,如何调出图层面板?

    什么是图层?如果有点PS基础的同学,应该会非常清楚这个概念,它是构成图像的重要组成单位,许多效果可以通过对层的直接操作而得到,并在当前图层操作时候不会影响到其他图层,所以在绘图的过程中有着很重要的作用 ...

  8. TF基础5

    卷积神经网络CNN 卷积神经网络的权值共享的网络结构显著降低了模型的复杂度,减少了权值的数量. 神经网络的基本组成包括输入层.隐藏层和输出层. 卷积神经网络的特点在于隐藏层分为卷积层和池化层. pad ...

  9. 基于Nginx服务的用户认证

    通过Nginx实现web页面的用户认证,用户名为:admin,密码为:654321 1.修改Nginx配置文件 # vim /usr/local/nginx/conf/nginx.conf ..... ...

  10. java 常用API

    package com.orcal.demc01; public class Regex { public static void main(String[] args) { // TODO Auto ...