好久没有更blog了啊。。。

对于一个给定长度为N的字符串,求它的第K小子串是什么。

这是一个SAM的模板题。

我好弱啊这个时候才开始学SAM,才会用指针。

要维护3个东西:每个状态right集合的大小、每个状态能到达的所有状态的right集合总大小、每个状态能到达的所有状态数

我没有判-1的情况反正没有-1的数据也能过

//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
#define ll long long
const int maxn=5e5+10;
int n,k,o;
char s[maxn]; char cc;ll ff;
template<typename T>void read(T& aa) {
aa=0;ff=1; cc=getchar();
while(cc!='-'&&(cc<'0'||cc>'9')) cc=getchar();
if(cc=='-') ff=-1,cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
aa*=ff;
} struct Sam{
Sam *next[27],*par;
int step;ll right,sum[2];
}pool[2*maxn],*last,*root;
int tot; Sam* newnode(int step) {
Sam* t=pool+(tot++);
memset(t->next,0,sizeof(t->next));
t->par=NULL;
t->step=step;
t->right=t->sum[0]=t->sum[1]=0;
return t;
} void Extend(int w) {
Sam *p=last;
Sam *np=newnode(p->step+1);np->right=1;
for(;p&&!p->next[w];p=p->par) p->next[w]=np;
if(!p) np->par=root;
else {
Sam *q=p->next[w];
if(q->step==p->step+1) np->par=q;
else {
Sam *nq=newnode(p->step+1);
memcpy(nq->next,q->next,sizeof(q->next));
nq->par=q->par;
q->par=nq; np->par=nq;
for(;p&&p->next[w]==q;p=p->par) p->next[w]=nq;
}
}
last=np;
} int c[2*maxn];Sam *sa[2*maxn];
void get_jp() {
Sam *r,*t;
for(r=pool+1;r!=pool+tot;++r) c[r->step]++;
for(int i=1;i<=n;++i) c[i]+=c[i-1];
for(r=pool+1;r!=pool+tot;++r) sa[c[r->step]--]=r;
for(int i=tot-1;i;--i) {
r=sa[i];
r->sum[0]=1;
r->sum[1]=r->right;
t=r->par;
t->right+=r->right;
for(int j=0;j<26;++j) {
t=r->next[j];
if(!t) continue;
r->sum[0]+=t->sum[0];
r->sum[1]+=t->sum[1];
}
}
} void travel() {
Sam *r=root,*t;
while(k) {
for(int i=0;i<26&&k;++i) {
t=r->next[i];
if(!t) continue;
if(t->sum[o]>=k) {
printf("%c",i+'a');
break;
}
k-=t->sum[o];
}
r=t;
if(o==1&&k<=r->right) break;
if(o==0&&k<=1) break;
k-= o==0? 1 : r->right;
}
} int main() {
scanf("%s",s+1); n=strlen(s+1);
last=root=newnode(0);
for(int i=1;i<=n;++i) Extend(s[i]-'a');
get_jp();
read(o); read(k);
travel();
return 0;
}

  

顺便再放一道水题(spoj8222)的代码

//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
#define ll long long
const int maxn=250000+7;
int n,ans[maxn];
char s[maxn]; char cc;ll ff;
template<typename T>void read(T& aa) {
aa=0;ff=1; cc=getchar();
while(cc!='-'&&(cc<'0'||cc>'9')) cc=getchar();
if(cc=='-') ff=-1,cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
aa*=ff;
} struct Sam{
Sam *next[27],*par;
int step,right;
}pool[2*maxn],*last,*root;
int tot; Sam* newnode(int step) {
Sam *t=pool+(tot++);
memset(t->next,0,sizeof(t->next));
t->step=step; t->right=0;
return t;
} void Extend(int w) {
Sam *p=last;
Sam *np=newnode(p->step+1); np->right=1;
for(;p&&!p->next[w];p=p->par) p->next[w]=np;
if(!p) np->par=root;
else {
Sam *q=p->next[w];
if(q->step==p->step+1) np->par=q;
else {
Sam *nq=newnode(p->step+1);
memcpy(nq->next,q->next,sizeof(q->next));
nq->par=q->par;
q->par=nq; np->par=nq;
for(;p&&p->next[w]==q;p=p->par) p->next[w]=nq;
}
}
last=np;
} int c[2*maxn];Sam *sa[2*maxn];
void csort() {
Sam *t;
for(t=pool+1;t!=pool+tot;++t) c[t->step]++;
for(int i=1;i<=n;++i) c[i]+=c[i-1];
for(t=pool+1;t!=pool+tot;++t) sa[c[t->step]--]=t;
for(int i=tot-1;i;--i) {
t=sa[i];
ans[t->step]=max(ans[t->step],t->right);
t->par->right+=t->right;
}
} int main() {
scanf("%s",s+1); last=root=newnode(0);
n=strlen(s+1);
for(int i=1;i<=n;++i) Extend(s[i]-'a');
csort();
for(int i=n;i;--i) ans[i]=max(ans[i],ans[i+1]);
for(int i=1;i<=n;++i) printf("%d\n",ans[i]);
return 0;
}

  

bzoj3899 弦论的更多相关文章

  1. 【BZOJ-3998】弦论 后缀自动机

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

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

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

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

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

  4. Luogu P3975 [TJOI2015]弦论

    题目链接 \(Click\) \(Here\) 题目大意: 重复子串不算的第\(k\)大子串 重复子串计入的第\(k\)大子串 写法:后缀自动机. 和\(OI\) \(Wiki\)上介绍的写法不太一样 ...

  5. BZOJ3899 仙人掌树的同构(圆方树+哈希)

    考虑建出圆方树.显然只有同一个点相连的某些子树同构会产生贡献.以重心为根后(若有两个任取一个即可),就只需要处理子树内部了. 如果子树的根是圆点,其相连的同构子树可以任意交换,方案数乘上同构子树数量的 ...

  6. LG3975 [TJOI2015]弦论

    题意 题目描述 为了提高智商,ZJY开始学习弦论.这一天,她在< String theory>中看到了这样一道问题:对于一个给定的长度为n的字符串,求出它的第k小子串是什么.你能帮帮她吗? ...

  7. 洛谷 P3975 [TJOI2015]弦论 解题报告

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

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

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

  9. 洛谷 P3975 / loj 2102 [TJOI2015] 弦论 题解【后缀自动机】【拓扑排序】

    后缀自动机入门. 题目描述 为了提高智商,ZJY 开始学习弦论. 这一天,她在<String theory>中看到了这样一道问题:对于一个给定的长度为 \(n\) 的字符串,求出它的第 \ ...

随机推荐

  1. OpenGL学习笔记2017/8/29

    OpenGL学习日志: 感谢doing5552 的OpenGL入门学习:http://www.cppblog.com/doing5552/archive/2009/01/08/71532.html 相 ...

  2. Python ——tempfile

    主要有以下几个函数: tempfile.TemporaryFile 如何你的应用程序需要一个临时文件来存储数据,但不需要同其他程序共享,那么用TemporaryFile函数创建临时文件是最好的选择.其 ...

  3. 阿里云 Aliplayer高级功能介绍(六):进度条标记

    基本介绍 Aliplayer在进度条上提示时间和缩略图功能外,还可以进行视频内容的提示打点,当然不止是进度条上显示打点的内容,还提供一组接口,方便用户进行打点时间和内容的获取, 基本UI如下图所示: ...

  4. PostgreSQL 优化器代码概览

    简介 PostgreSQL 的开发源自上世纪80年代,它最初是 Michael Stonebraker 等人在美国国防部支持下创建的POSTGRE项目.上世纪末,Andrew Yu 等人在它上面搭建了 ...

  5. javascript 的原始数据类型

     javascript 的原始数据类型有五种,分别是Number.String.Boolean.null.undefined   原始类型数据的特点:值保存在变量本地,且赋值给其他变量后,其它变量改变 ...

  6. Django中间件初始化过程

    def load_middleware(self): """ Populate middleware lists from settings.MIDDLEWARE. Mu ...

  7. 一、WebService基础概念

    一.Web Service简介 1.1.Web Service基本概念 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intrane ...

  8. Java程序员面试题收集(6)

    <!————————————————————————————基础题122道,代码题19道————————————————————————————> JAVA相关基础知识1.面向对象的特征有 ...

  9. StopWatch 监控Java代码运行时间和分析性能

    背景 有时我们在做开发的时候需要记录每个任务执行时间,或者记录一段代码执行时间,最简单的方法就是打印当前时间与执行完时间的差值,然后这样如果执行大量测试的话就很麻烦,并且不直观,如果想对执行的时间做进 ...

  10. 2019-10-11-VisualStudio-配置多进程调试快捷键启动项目

    title author date CreateTime categories VisualStudio 配置多进程调试快捷键启动项目 lindexi 2019-10-11 15:33:32 +080 ...