时隔一年再回归w

这题用后缀数组来做的话,主要就是t=1时比较麻烦。考虑可以想办法得到一个前缀和,求出到排名为i的后缀一共有多少子串。之后再二分找到第k个子串在哪个后缀里。

求前缀和时,对于相同的子串,要在排名靠后的后缀长度中减去它,同时全部加到包含该子串的排名最靠前的后缀中。这个操作可以利用单调队列完成,既要更新一个后缀中包含的子串数目,也要同时记录每个有重复的子串长度和重复次数。二分找到包含目标子串的后缀后,用先前记录的重复子串情况,对该后缀从后向前逐位找到目标子串右端点。

稍微注意一下long long的问题吧。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=500010;
struct node{int len,cnt,pos;
}mem[N];
int type,k,n,m,num,a[N],hgt[N],sa[N],rnk[N],tp[N],tak[N],q1[N],pos[N],op,cl;
char str1[N];
long long tot[N];
inline void sort1(){for(int i=1;i<=m;++i)tak[i]=0;for(int i=1;i<=n;++i)++tak[rnk[i]];for(int i=2;i<=m;++i)tak[i]+=tak[i-1];for(int i=n;i>=1;--i)sa[tak[rnk[tp[i]]]--]=tp[i];
}
int main(){scanf("%s",str1+1);n=strlen(str1+1);scanf("%d%d",&type,&k);for(int i=1;i<=n;++i)rnk[i]=str1[i]-'a'+1,tp[i]=i;m=26;sort1();for(int w=1,p=0;p<n;m=p,w<<=1){p=0;for(int i=1;i<=w;++i)tp[++p]=n-w+i;for(int i=1;i<=n;++i)if(sa[i]>w)tp[++p]=sa[i]-w;sort1();swap(tp,rnk);p=rnk[sa[1]]=1;for(int i=2;i<=n;++i){if(tp[sa[i]]!=tp[sa[i-1]]||tp[sa[i]+w]!=tp[sa[i-1]+w])++p;rnk[sa[i]]=p;}}for(int x,j=0,i=1;i<=n;++i){if(j)--j;x=sa[rnk[i]-1];while(str1[x+j]==str1[i+j])++j;hgt[rnk[i]]=j;}if(!type){for(int s=k,i=1;i<=n;i++){if(s>n-sa[i]+1-hgt[i])s-=n-sa[i]+1-hgt[i];else{for(int j=0;j<hgt[i];j++)printf("%c",str1[sa[i]+j]);for(int j=0;j<s;j++)printf("%c",str1[sa[i]+hgt[i]+j]);return 0;}}printf("-1");}else{for(int i=1;i<=n;++i)tot[i]=(n-sa[i]-hgt[i]+1)*1ll;hgt[n+1]=num=0,op=1,cl=0;for(int s,i=2;i<=(n+1);++i){s=i;while(op<=cl&&hgt[i]<=q1[cl]){if(hgt[i]!=q1[cl]){int del=q1[cl]-max(hgt[pos[cl]-1],hgt[i]);mem[++num].pos=pos[cl]-1,mem[num].cnt=i-pos[cl]+1,mem[num].len=q1[cl],tot[pos[cl]-1]+=(mem[num].cnt-1)*(del)*1ll;}s=pos[cl];--cl;}q1[++cl]=hgt[i],pos[cl]=s;}for(int i=2;i<=n;++i)tot[i]+=tot[i-1];int l=1,r=n,mid;long long kk=k*1ll;while(l<=r){mid=(l+r)>>1;if(tot[mid]<kk)l=mid+1;else r=mid-1;}if(l>n){printf("-1");return 0;}for(int i=1;i<=num;++i)if(mem[i].pos==l)a[mem[i].len]=mem[i].cnt;for(int mx=1,i=n-sa[l]+1;i>hgt[l];--i)if(a[i])mx=a[i];else a[i]=mx;for(int i=n;i>=sa[l];--i){tot[l]-=a[i-sa[l]+1]*1ll;if(tot[l]<kk){for(int j=sa[l];j<=i;++j)printf("%c",str1[j]);break;}}}return 0;
}

[P3975][TJOI2015]弦论(后缀数组)相关推荐

  1. 洛谷 - P3975 [TJOI2015]弦论(后缀自动机)

    题目链接:点击查看 题目大意:给出一个字符串 s,再给出一次询问,询问分为两种类型: 0 k:如果不同位置的相同子串算作一个,求第 k 小的子串 1 k:如果不同位置的相同子串算作多个,求第 k 小的 ...

  2. 【题解】P3975 [TJOI2015]弦论 后缀自动机

    给定一个长度为n(5e5)的字符串,求它字典序第k小的子串. 输入还有一个t,t=0时表示不同位置的相同子串算作一个,t=1表示不同位置的相同子串算作多个. 使用后缀自动机. 后缀自动机中的每条路径对 ...

  3. P3975 [TJOI2015]弦论 - 后缀自动机(SAM)

    这是一道板子题的改编,意在加深对求第k小子串的理解.首先先看一下最简单的SAM板子.相信应该都写过了才会写这题 // // Created by acer on 2021/2/16. // //判断子 ...

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

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

  5. 洛谷 [P3975 [TJOI2015]弦论

    洛谷 P3975 [TJOI2015]弦论 题目描述 给定一个长度为 nnn 的字符串,求它的第 kkk 小字串:给定 ttt, ttt 为 000 则表示不同位置的相同子串算作一个,ttt 为 11 ...

  6. luogu P3975 [TJOI2015]弦论 SAM

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

  7. 【后缀自动机】Luogu P3975 [TJOI2015]弦论题解

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

  8. P3975 [TJOI2015]弦论 (SAM)

    [TJOI2015]弦论 - 洛谷 感觉位置不同算相同还是比较好想的,我们top排序后算每个点后面连接了多少点就知道里面有多少字串了,然后求k大就行了: 考了位置不同算不同的话,我们就要考虑endpo ...

  9. 洛谷P3975 - [TJOI2015]弦论

    Portal Description 给出一个小写字母串\(s(|s|\leq5\times10^5),t\in\{0,1\},k(k\leq10^9)\),求\(s\)的第\(k\)小子串.\(t= ...

最新文章

  1. 硬链接与软链接的区别有哪些?
  2. lvs工作在第几层_lvs负载均衡算法工作在哪一层
  3. C# 学习笔记(13)自己的串口助手
  4. 操作多个表_3_查询两个表共同的行
  5. Scala 开发 Spark 程序
  6. seaborn画图设置横纵坐标标签
  7. python 图片转文字错误_python3把base64字符串写成图片文件出错
  8. windows下release模式调试某行代码无法中断
  9. python中循环结构break_Python编程10:跳出循环结构之break和continue
  10. original:,tool:AAPT
  11. ant design of vue 组件库
  12. Techme INC:这5类人要警惕癌症!
  13. 尺度空间-多尺度特征空间
  14. 硬件设计必备,电子元器件高清矢量图
  15. 大佬云集的在线少儿英语市场,谁才是那匹冲出重围的黑马?
  16. TensorFlow Lite(实战系列一):TFLite Android 迁移训练构建自己的图像识别APP
  17. php短信验证案例,PHP项目之容联云短信发送验证码
  18. Angular *NgFor - angular 基础教程
  19. 郑州73中学计算机老师,2019年关于“郑州市中学信息技术优质课评比”的通知
  20. 应届生前端面试题笔记

热门文章

  1. 使用Stream操作List
  2. 出货量差距大幅缩短,四季度小米可望彻底击败华为!
  3. 微信公众号中的支付宝支付与微信支付 支付宝支付问题(微信bug)
  4. openlayers划线、标记点
  5. 哪款护眼灯最适合学生?教育部入围护眼照明品牌
  6. 一个创业项目成功需要具备什么条件?
  7. el-tree实现类似windows文件列表,并支持折叠、展开和重命名
  8. 达达,不想跳出京东舒适圈
  9. div+CSS浏览器兼容问题整理(IE6.0、IE7.0 ,ie8 , FireFox...)
  10. mysql数据库清空表格中数据恢复