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\) 的字符串,求出它的第 \ ...
随机推荐
- DataLakeAnalytics: 解析IP地址对应的国家城市地址的能力
Data Lake Analytics 作为云上数据处理的枢纽,最近加入了通过IP地址查找对应的国家.省份.城市.ISP的函数, 今天带大家体验一下. 函数详细介绍 本次一共添加了下面这些函数: ip ...
- $cordovaNetwork 使用
1 .安装插件 直接安装: cordova plugin add cordova-plugin-network-information 下载到本地安装: https://github.com/apac ...
- Extjs 疑难杂症 (LoadMark 遮罩、Panel Update无效、chrome浏览器date控件全屏)
一.在extjs gridPanel中使用LoadMark无效,三步搞定. 原代码: grid = new Ext.grid.GridPanel({ store: store, title:'资料列表 ...
- jeecms项目相关配置文件
1.application-context.xml 这个是Spring的标准配置文件,这里面配置jdbc.properties文件并初始化相应数据库连接参数到bean实例:定义数据库表映射文件*.hb ...
- Spring AOP(三)--XML方式实现
本文介绍通过XML方式实现Spring AOP,在上一篇中已经介绍了通过注解+java配置的方式,这篇文章主要是看XML中怎么配置,直接上代码了: 一.创建一个连接点 1⃣️定义接口 注意⚠️:可以定 ...
- 注册.NET Framework
C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe /i
- 在银行业中,BP是指什么?
基点 Basis Point(BP)债券和票据利率改变量的度量单位.一个基点等于0.01个百分点,即0.01%,因此,100个基点等于1%.[例]一浮动利率债券的利率可能比LIBOR高10个基点,10 ...
- 【vue】vue-znly
老规矩,放下博主的项目地址:https://github.com/wohaiwo/vue-znly 我一直在想给那些开源者取什么名字比较好,怎样才对得起他们开源项目的精神,后来想想,还是叫博主吧.有的 ...
- JavaScript内容梳理 示例之模态对话框 示例之全选和反选以及取消 示例之后台管理左侧菜单
<!DOCTYPE html> <!--示例之模态对话框--> <html lang="en"> <head> <meta c ...
- CF 529B Group Photo 2 (online mirror version)
传送门 解题思路 这道题要用到贪心的思路,首先要枚举一个h的最大值,之后check.如果这个东西的w[i]与h[i]都大于枚举的值就直接return false,如果w[i]比这个值小,h[i]比这个 ...