好久没有更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. 百度ueditor解决页面组件被覆盖问题

    本文不再更新,可能存在内容过时的情况,实时更新请移步原文地址:百度ueditor解决页面组件被覆盖问题: 在使用ueditor的过程中,会出现表单组件被ueditor覆盖的问题,解决的方式如下: ue ...

  2. thinkcmf报错:fileowner(): stat failed for /sys

    thinkcmf转移到linux云服务器后,后台更新缓存页面报错,错误信息fileowner(): stat failed for /sys 临时解决办法:修改common.php cmf_clear ...

  3. java 用户注册登陆Demo

    一个用户注册登陆的系统,用到了MD5加密处理密码,实现了一个简单的数据库连接池connectionPool, 实现了注册,登陆,登陆之后修改用户信息等功能,非常适合初学者 一.准备工作 数据库:MyS ...

  4. DVWA 之medium级别sql注入

    中级注入的提交方式从get请求改为post请求,可以用burp抓包注入或抓注入点 1 .  判断是否有注入 sqlmap -u "http://192.168.242.1/dvw/vulne ...

  5. debian下编译安装poco

    系统环境: debian版本:Linux localhost.localdomain 3.10.0-862.14.4.el7.x86_64 #1 SMP Wed Sep 26 15:12:11 UTC ...

  6. 网络编程-基础篇03(I/O模型)

    好文传播,在此插个眼: 一文读懂高性能网络编程中的I/O模型

  7. A20地址线科普【转载】

    1981 年8 月,IBM 公司最初推出的个人计算机IBM PC 使用的CPU 是Intel 8088.在该微机中地址线只有20 根(A0 – A19).在当时内存RAM 只有几百KB 或不到1MB ...

  8. Javascript-简单的倒计时跳转页面

    <!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> ...

  9. Winform 分页

    1.图列展示 2.分页控件代码 Paging.Designer.cs partial class Paging { /// <summary> /// 必需的设计器变量. /// < ...

  10. 【python之路41】web框架

    一.web框架介绍 一共有两种web框架 1.既包含socket又能逻辑处理 tornado框架 2.只能处理逻辑 Django bottle flask  二.web框架的本质 众所周知,对于所有的 ...