bzoj3899 弦论
好久没有更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 弦论的更多相关文章
- 【BZOJ-3998】弦论 后缀自动机
3998: [TJOI2015]弦论 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2018 Solved: 662[Submit][Status] ...
- BZOJ 3998: [TJOI2015]弦论 [后缀自动机 DP]
3998: [TJOI2015]弦论 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2152 Solved: 716[Submit][Status] ...
- 【BZOJ3998】弦论(后缀自动机)
[BZOJ3998]弦论(后缀自动机) 题面 BZOJ 题解 这题应该很简单 构建出\(SAM\)后 求出每个点往后还能构建出几个串 按照拓扑序\(dp\)一些就好了 然后就是第\(k\)大,随便搞一 ...
- Luogu P3975 [TJOI2015]弦论
题目链接 \(Click\) \(Here\) 题目大意: 重复子串不算的第\(k\)大子串 重复子串计入的第\(k\)大子串 写法:后缀自动机. 和\(OI\) \(Wiki\)上介绍的写法不太一样 ...
- BZOJ3899 仙人掌树的同构(圆方树+哈希)
考虑建出圆方树.显然只有同一个点相连的某些子树同构会产生贡献.以重心为根后(若有两个任取一个即可),就只需要处理子树内部了. 如果子树的根是圆点,其相连的同构子树可以任意交换,方案数乘上同构子树数量的 ...
- LG3975 [TJOI2015]弦论
题意 题目描述 为了提高智商,ZJY开始学习弦论.这一天,她在< String theory>中看到了这样一道问题:对于一个给定的长度为n的字符串,求出它的第k小子串是什么.你能帮帮她吗? ...
- 洛谷 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 对于一 ...
- 洛谷 P3975 / loj 2102 [TJOI2015] 弦论 题解【后缀自动机】【拓扑排序】
后缀自动机入门. 题目描述 为了提高智商,ZJY 开始学习弦论. 这一天,她在<String theory>中看到了这样一道问题:对于一个给定的长度为 \(n\) 的字符串,求出它的第 \ ...
随机推荐
- Spring_关于@Resource注入为null解决办法
初学spring,我在dao层初始化c3p0的时候,使用@Resource注解新建对象是发现注入为null,告诉我 java.lang.NullPointerException. @Repositor ...
- 【codeforces 508D】Tanya and Password
[题目链接]:http://codeforces.com/problemset/problem/508/D [题意] 给你一个字符的所有连续3个的子串; 让你复原出原串; (包含小写.大写字母以及数字 ...
- org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.connections.spi.ConnectionProvider]
从hibernate3升级到4应该会遇到 应该添加引用 <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-c3p0 ...
- Python爬虫笔记【一】模拟用户访问之表单处理(3)
学习的课本为<python网络数据采集>,大部分代码来此此书. 大多数网页表单都是由一些HTML 字段.一个提交按钮.一个在表单处理完之后跳转的“执行结果”(表单属性action 的值)页 ...
- HDU 5266 pog loves szh III 线段树,lca
Pog and Szh are playing games. Firstly Pog draw a tree on the paper. Here we define 1 as the root of ...
- Leetcode441Arranging Coins排列硬币
你总共有 n 枚硬币,你需要将它们摆成一个阶梯形状,第 k 行就必须正好有 k 枚硬币. 给定一个数字 n,找出可形成完整阶梯行的总行数. n 是一个非负整数,并且在32位有符号整型的范围内. 示例 ...
- 【python之路23】递归
1.递归的基础 举例说明:老师要班里坐在最后的一排学生要一本书,老师对前面的人说你向最后一排的同学要一本书,那么最前面的人跟坐在第2排的人说,第2排的人跟第3排的人说,当命令传递到最后一排时,最后一排 ...
- JS---案例:大量字符串拼接效果实现
案例:大量字符串拼接效果实现 按钮点击,字符串拼接,最后效果字符串,str input有很多,type来分就有button和text,需要找出inputs[i].value是text的 所以用!=&q ...
- 基于python爬虫的github-exploitdb漏洞库监控与下载
基于python爬虫的github-exploitdb漏洞库监控与下载 offensive.py(爬取项目历史更新内容) #!/usr/bin/env python # -*- coding:utf- ...
- 前后端分离后API交互如何保证数据安全性
前后端分离后API交互如何保证数据安全性? 一.前言 前后端分离的开发方式,我们以接口为标准来进行推动,定义好接口,各自开发自己的功能,最后进行联调整合.无论是开发原生的APP还是webapp还是PC ...