LGOJ3975 TJOI2015 弦论
题目大意:
给定一个字符串,输出在对该字符串所有的非空子串排序后第\(k\)个
另外的一个限制是\(T\):子串本质相同但位置不同算\(1\)或多个
\(|s| \leq 5 \times 10^5\)
Solution
“子串排序”,而且数据比较大的时候就要想到后缀自动机了
这个过程有点点像我们在写Treap的时候(就是lyd的书上的代码吧,蒟蒻只学过那一个)
第一步构造一下,套个板子就行
接下来我们先看一下我们的输出代码:
inline void print(int x,int l)
{
if(l<=val[x]) return ;
l-=val[x];
for(int i=0;i<26;++i)
{
int r=p[x].ch[i]; if(!r) continue;
if(l>sum[r]){l-=sum[r]; continue;}
putchar(i+'a'); print(r,l); return ;
}
}
\(x\)是当前是哪个节点,\(l\)就是还剩下多少的排位
\(val[]\)就是“本质相同串”,有点点类似我们在\(Treap\)上的每一个节点的\(size\)
\(sum[]\)就是子树大小
和\(treap\)找\(rank\)太像了(反正我觉得是)
然后我们的工作就转化成了维护\(sum[]\)的\(val[]\)
看看这段维护代码,一点一点说吧(如果是有学习需要的访客,请跳过这段代码解释,可能有锅)
for(int i=1;i<=tot;++i) t[len(i)]++;
for(int i=1;i<=tot;++i) t[i]+=t[i-1];
for(int i=1;i<=tot;++i) a[t[len(i)]--]=i;
//上文都是自动机上的操作
//下文就是大力统计“和”
for(int i=tot;i>=1;--i) val[fa(a[i])]+=val[a[i]];
for(int i=1;i<=tot;++i) cas==0?(sum[i]=val[i]=1):(sum[i]=val[i]);
val[1]=sum[1]=0;
for(int i=tot;i>=1;--i)
{
for(int j=0;j<26;++j)
{
if(p[a[i]].ch[j]) sum[a[i]]+=sum[p[a[i]].ch[j]];
}
}
其实到这里我认为是可理解的(博主理解了)
CODE
#include<bits/stdc++.h>
using namespace std;
#define int long long
namespace yspm{
inline int read()
{
int res=0,f=1;char k;
while(!isdigit(k=getchar())) if(k=='-') f=-1;
while(isdigit(k)) res=res*10+k-'0',k=getchar();
return res*f;
}
const int N=2e6+10;
char s[N];
struct node{
int fa,len,ch[26];
#define fa(x) p[x].fa
#define len(x) p[x].len
}p[N];
int t[N],a[N],sum[N],k,las=1,tot=1,len,cas,val[N];
inline void addp(int x)
{
int tmp=las,np=las=++tot; val[tot]=1; p[np].len=p[tmp].len+1;
for(;tmp&&!p[tmp].ch[x];tmp=p[tmp].fa) p[tmp].ch[x]=np;
if(!tmp) p[np].fa=1;
else
{
int q=p[tmp].ch[x];
if(p[q].len==p[tmp].len+1) p[np].fa=q;
else
{
int nq=++tot;
p[nq]=p[q]; p[nq].len=p[tmp].len+1;
p[q].fa=p[np].fa=nq;
for(;tmp&&p[tmp].ch[x]==q;tmp=p[tmp].fa) p[tmp].ch[x]=nq;
}
} return ;
}
inline void print(int x,int l)
{
if(l<=val[x]) return ;
l-=val[x];
for(int i=0;i<26;++i)
{
int r=p[x].ch[i]; if(!r) continue;
if(l>sum[r]){l-=sum[r]; continue;}
putchar(i+'a'); print(r,l); return ;
}
}
signed main()
{
scanf("%s",s+1); cas=read(); k=read(); len=strlen(s+1);
for(int i=1;i<=len;++i) addp(s[i]-'a');
for(int i=1;i<=tot;++i) t[len(i)]++;
for(int i=1;i<=tot;++i) t[i]+=t[i-1];
for(int i=1;i<=tot;++i) a[t[len(i)]--]=i;
for(int i=tot;i>=1;--i) val[fa(a[i])]+=val[a[i]];
for(int i=1;i<=tot;++i) cas==0?(sum[i]=val[i]=1):(sum[i]=val[i]);
val[1]=sum[1]=0;
for(int i=tot;i>=1;--i)
{
for(int j=0;j<26;++j)
{
if(p[a[i]].ch[j]) sum[a[i]]+=sum[p[a[i]].ch[j]];
}
}
if(sum[1]<k) puts("-1");
else print(1,k),puts("");
return 0;
}
}signed main(){return yspm::main();}
LGOJ3975 TJOI2015 弦论的更多相关文章
- BZOJ 3998: [TJOI2015]弦论 [后缀自动机 DP]
3998: [TJOI2015]弦论 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2152 Solved: 716[Submit][Status] ...
- Luogu P3975 [TJOI2015]弦论
题目链接 \(Click\) \(Here\) 题目大意: 重复子串不算的第\(k\)大子串 重复子串计入的第\(k\)大子串 写法:后缀自动机. 和\(OI\) \(Wiki\)上介绍的写法不太一样 ...
- 洛谷 P3975 [TJOI2015]弦论 解题报告
P3975 [TJOI2015]弦论 题目描述 为了提高智商,ZJY开始学习弦论.这一天,她在<String theory>中看到了这样一道问题:对于一个给定的长度为\(n\)的字符串,求 ...
- 【BZOJ 3998】 3998: [TJOI2015]弦论 (SAM )
3998: [TJOI2015]弦论 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2627 Solved: 881 Description 对于一 ...
- 【BZOJ3998】[TJOI2015]弦论 后缀自动机
[BZOJ3998][TJOI2015]弦论 Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T ...
- BZOJ_3998_[TJOI2015]弦论_后缀自动机
BZOJ_3998_[TJOI2015]弦论_后缀自动机 Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行 ...
- bzoj3998: [TJOI2015]弦论(SAM+dfs)
3998: [TJOI2015]弦论 题目:传送门 题解: SAM的入门题目(很好的复习了SAM并加强Right集合的使用) 其实对于第K小的字符串直接从root开始一通DFS就好,因为son边是直接 ...
- luogu P3975 [TJOI2015]弦论 SAM
luogu P3975 [TJOI2015]弦论 链接 bzoj 思路 建出sam. 子串算多个的,统计preant tree的子树大小,否则就是大小为1 然后再统计sam的节点能走到多少串. 然后就 ...
- 题解-TJOI2015 弦论
TJOI2015 弦论 字符串 \(s\) 和 \(t\) 和 \(k\).如果 \(t=0\),不同位置的相同子串算 \(1\) 个:如果 \(t=1\),不同位置的相同子串算多个.求 \(k\) ...
随机推荐
- ORACLE常见问题收集
1.Java代码执行oracle,update和insert语句卡住不动 解决方法:造成这样的情况原因在于你之前执行了update或insert操作但你并没有commit,导致你操作的这条记录被ora ...
- CDH6.2安装配置第二篇:CDH安装的前期配置
本篇介绍cdh安装之前需要的一些必要配置,当然这些配置也可以用shell脚本来配置.在安装之前请先配置好yum源,在文中用的统一都是阿里源.在安装的时候,要确保主机的内存是4G以上,要不然会无限重启c ...
- 解决XML警告"No grammar constraints (DTD or XML Schema) referenced in the document"
解决办法: 顶部有这两行信息即可解决警告: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ...
- Jenkins 插件中心国内镜像源发布
以下文章来源于Jenkins,作者LinuxSuRen Jenkins 社区的网络基础设施都是架设在国外的服务器上,而且,并没有在国内有 CDN 或者负载均衡的配置.对所有的 Jenkins 用户而言 ...
- 吴裕雄--天生自然MySQL学习笔记:MySQL 创建数据库
在登陆 MySQL 服务后,使用 create 命令创建数据库,语法如下: CREATE DATABASE 数据库名; 以下命令简单的演示了创建数据库的过程,数据名为 RUNOOB: [root@ho ...
- UML-逻辑架构精化
向下请求:Facade模式 向上返回:观察者模式 不局限于上图中指定的层使用相应模式,其他层也可以使用. 另外,尽量不要出现“公共业务模块”,设计时尽量做好系统拆分.否则,一旦修改公共代码,可能会影响 ...
- 【转帖】使用容器化和 Docker 实现 DevOps 的基础知识
使用容器化和 Docker 实现 DevOps 的基础知识 https://www.kubernetes.org.cn/6730.html 2020-02-24 15:20 灵雀云 分类:容器 阅读( ...
- 当初希望自己是如何投入这个专业的学习的?曾经做过什么准备,或者立下过什么FLAG吗?
学习好累,打游戏好爽 我不爱学习 认真勤勉投入学习 精心准备,刻苦学习 我的flag 作为大学生,需要了解今后职场社会,对职业方向有了进一步的认识.社会对于人才的要求在某些方面都是不谋而合的,比 ...
- Python基础学习二
Python基础学习二 1.编码 utf-8编码:自动将英文保存为1个字符,中文3个字符.ASCll编码被囊括在内. unicode:将所有字符保存为2给字符,容纳了世界上所有的编码. 2.字符串内置 ...
- dfs--迷宫
题目背景 给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过.给定起点坐标和终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案.在迷宫中移动有上下左右四种方式,每次只能移 ...