我们先求出该字符串的\(SA\)和\(Ht\)

然后分类讨论

\(T=0\)时,每次去掉\(Ht\)往后扫就行

\(T=1\)时,我们考虑\(lcp\)对答案的影响

既然用到\(lcp\),那就要用\(ST\)表维护

左端点固定时,随右端点的增大,区间\(\min\)单调不升

我们就可以用二分+限制右端点的方式统计某个后缀的前缀的贡献

循环遍历每个后缀时,由于\(Ht\)部分已经统计过对答案的贡献,就不用再计算了,从\(Ht+1\)的位置继续向后统计即可

#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std; const int MAXN=5e5+5; int ln,maxn,p,t;
int SA[MAXN],id[MAXN],rnk[MAXN],bnk[MAXN],Ht[MAXN];
char ch[MAXN];
int ST[19][MAXN],lg[MAXN]; void shel()
{
for(int i=1;i<=ln;++i) ++bnk[rnk[id[i]]];
for(int i=1;i<=maxn;++i) bnk[i]+=bnk[i-1];
for(int i=1;i<=ln;++i) SA[++bnk[rnk[id[i]]-1]]=id[i];
for(int i=0;i<=maxn;++i) bnk[i]=0;
return;
} void GetSA()
{
for(int i=1;i<=ln;++i) rnk[i]=ch[i],id[i]=i,maxn=max(maxn,rnk[i]);
shel();
for(int k=1;k<ln;k<<=1){
for(int i=1;i<=k;++i) id[i]=ln-k+i;
int ct=k;
for(int i=1;i<=ln;++i) if(SA[i]>k) id[++ct]=SA[i]-k;
shel();swap(id,rnk);rnk[SA[1]]=1;
for(int i=2;i<=ln;++i) rnk[SA[i]]=(id[SA[i]]==id[SA[i-1]]&&id[SA[i]+k]==id[SA[i-1]+k])?rnk[SA[i-1]]:rnk[SA[i-1]]+1;
if(rnk[SA[ln]]==ln) return;
maxn=rnk[SA[ln]];
}return;
} void GetHt()
{
int k=0;
for(int i=1;i<=ln;++i){
if(rnk[i]==1) continue;
if(k) --k;
int ct=SA[rnk[i]-1];
while(ct+k<=ln&&i+k<=ln&&ch[i+k]==ch[ct+k]) ++k;
Ht[rnk[i]]=k;
}return;
} int Getmi(int l,int r){int tmp=lg[r-l+1];return min(ST[tmp][l+(1<<tmp)-1],ST[tmp][r]);} void slv1()
{
for(int i=1;i<=ln;++i) lg[i]=i>>lg[i-1]+1?lg[i-1]+1:lg[i-1];
for(int i=1;i<=ln;++i) ST[0][i]=Ht[i];
for(int j=1;j<=lg[ln];++j){
int tmp=1<<j-1;
for(int i=tmp<<1;i<=ln;++i){
ST[j][i]=min(ST[j-1][i],ST[j-1][i-tmp]);
}
}for(int i=1;i<=ln;++i){
int tmp=SA[i]+Ht[i];
int ct=ln;
while(1){
if(tmp>ln) break;
if(ct==i){
if(t>ln-tmp+1){t-=ln-tmp+1;break;}
for(int j=SA[i];j<=tmp+t-1;++j) putchar(ch[j]);
return;
}int l=i,r=ct;
while(l<r){
int mid=l+r+1>>1;
if(Getmi(i+1,mid)>=tmp-SA[i]+1) l=mid;
else r=mid-1;
}ct=r;
if(t>r-i+1) t-=r-i+1;
else{
for(int j=SA[i];j<=tmp;++j) putchar(ch[j]);
return;
}++tmp;
}
}puts("-1");
return;
} void slv2()
{
int ct=1;
while(t>ln-SA[ct]-Ht[ct]+1) t-=ln-SA[ct]-Ht[ct]+1,++ct;
if(ct>ln){puts("-1");return;}
for(int i=SA[ct];i<=SA[ct]+t+Ht[ct]-1;++i) putchar(ch[i]);
puts("");
return;
} int main()
{
scanf("%s",ch+1);ln=strlen(ch+1);
GetSA();GetHt();scanf("%d%d",&p,&t);
p?slv1():slv2();
return 0;
}

[TJOI2015]弦论的更多相关文章

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

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

  2. Luogu P3975 [TJOI2015]弦论

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

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

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

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

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

  5. 【BZOJ3998】[TJOI2015]弦论 后缀自动机

    [BZOJ3998][TJOI2015]弦论 Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行为两个整数T ...

  6. BZOJ_3998_[TJOI2015]弦论_后缀自动机

    BZOJ_3998_[TJOI2015]弦论_后缀自动机 Description 对于一个给定长度为N的字符串,求它的第K小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串S 第二行 ...

  7. bzoj3998: [TJOI2015]弦论(SAM+dfs)

    3998: [TJOI2015]弦论 题目:传送门 题解: SAM的入门题目(很好的复习了SAM并加强Right集合的使用) 其实对于第K小的字符串直接从root开始一通DFS就好,因为son边是直接 ...

  8. luogu P3975 [TJOI2015]弦论 SAM

    luogu P3975 [TJOI2015]弦论 链接 bzoj 思路 建出sam. 子串算多个的,统计preant tree的子树大小,否则就是大小为1 然后再统计sam的节点能走到多少串. 然后就 ...

  9. LGOJ3975 TJOI2015 弦论

    link:TJOI2015 弦论 题目大意: 给定一个字符串,输出在对该字符串所有的非空子串排序后第\(k\)个 另外的一个限制是\(T\):子串本质相同但位置不同算\(1\)或多个 \(|s| \l ...

  10. 题解-TJOI2015 弦论

    TJOI2015 弦论 字符串 \(s\) 和 \(t\) 和 \(k\).如果 \(t=0\),不同位置的相同子串算 \(1\) 个:如果 \(t=1\),不同位置的相同子串算多个.求 \(k\) ...

随机推荐

  1. Windows打开应用,提示“此程序被组策略阻止”

    Windows打开应用,提示"此程序被组策略阻止",该问题为组策略限制了用户使用某个应用程序,一般可以在 1 控制面板--->管理工具--->本地安全策略-->软 ...

  2. a 便签实现 下载

    如果想通过纯前端技术实现文件下载,直接把a标签的href属性设置为文件路径即可,如下: <a href="https://cdn.shopify.com/s/files/1/1545/ ...

  3. lnmp平台搭设

    软件链接:https://pan.baidu.com/s/14gAZ67iXWhEdzvEXMiGfVg             提取码:ai1s 只是在一台服务器上搭设,为centos7.2环境 安 ...

  4. 【xsy2193】Wallace 最大权闭合子图

    题目大意:给你一棵$n$个节点的树$a$,每个点有一个点权$val_i$,同时给你另一棵$n$个节点的树$b$. 现在你需要在树$a$上找一个联通块,满足这些点在树$b$上也是连通的,同时树$a$的这 ...

  5. Django url分发器

    视图: 视图一般都写在app的views.py中.并且视图的第一个参数永远都是request(一个HttpRequest)对象.这个对象存储了请求过来的所有信息,包括携带的参数以及一些头部信息等.在视 ...

  6. oracle 切换用户操作--or--sys用户密码忘记

    1.sqlplus中以普通用户登录oracle后, 普通用户的登录方式: sqlplus /nolog conn 用户名/密码@IP地址/orcl:1521; 这个时候,想要切换sys用户,conn ...

  7. 使用.NetCore在Linux上写TCP listen 重启后无法绑定地址

    拥抱.net core的过程中, 将公司的一套java项目改成了.net core 2.0版的. 里面的tcp服务被我用msdn的SocketAsyncEventArgs方式重写了, 然而在测试的过程 ...

  8. gridvew使用技巧2

    GridVew1_RowDataBindGridView1.DataKeys[e.Row.RowIndex].Values[].ToString(); foreach (GridViewRow t i ...

  9. CVPR2019 | Mask Scoring R-CNN 论文解读

    Mask Scoring R-CNN CVPR2019 | Mask Scoring R-CNN 论文解读 作者 | 文永亮 研究方向 | 目标检测.GAN 推荐理由: 本文解读的是一篇发表于CVPR ...

  10. mysql 删除单表内多个字段重复的数据

    mysql 删除单表内多个字段重复的数据 DELETE from lot_log_payflow WHERE (pay_no,sub_flow_type) in () s1) AND id ) s2) ...