题目链接:hdu 5008 Boring String Problem

题意:

给你一个字符串,有q个询问,每次询问该字符串所有的子串中字典序第k小的是哪个串,输出位置,如果有多个位置,输出最靠左的那个。

题解:

后缀数组求完height后,求一下字典序第i的后缀有多少个不同的子串,然后求一下前缀和。

然后就可以每对于一个k,可以二分求到排序后第一个字典序为k的后缀,然后用rmq求一下最小就行了。

 1 #include<bits/stdc++.h>
 2 #define mst(a,b) memset(a,b,sizeof(a))
 3 #define F(i,a,b) for(int i=(a);i<=(b);++i)
 4 #define ___ freopen("c:\\code\\in.txt","r",stdin);
 5 inline int RT(int l,int r){return l+r|l!=r;}
 6 using namespace std;
 7 typedef long long ll;
 8 typedef pair<int,int>P;
 9
10 namespace suffixarray{
11     #define FN(n) for(int i=0;i<n;i++)
12     const int N =1E5+7;
13     int rnk[N],sa[N],height[N],c[N];char s[N];
14     void getsa(int n,int m,int *x=rnk,int *y=height){
15         FN(m)c[i]=0;FN(n)c[x[i]=s[i]]++;FN(m)c[i+1]+=c[i];
16         for(int i=n-1;i>=0;i--)sa[--c[x[i]]]=i;
17         for(int k=1,p;p=0,k<=n;k=p>=n?N:k<<1,m=p){
18             for(int i=n-k;i<n;i++)y[p++]=i;
19             FN(n)if(sa[i]>=k)y[p++]=sa[i]-k;
20             FN(m)c[i]=0;FN(n)c[x[y[i]]]++;FN(m)c[i+1]+=c[i];
21             for(int i=n-1;i>=0;i--)sa[--c[x[y[i]]]]=y[i];
22             swap(x,y),p=1,x[sa[0]]=0;
23             for(int i=1;i<n;i++)
24             x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++;
25         }
26         FN(n)rnk[sa[i]]=i;
27         for(int i=0,j,k=0;i<n-1;height[rnk[i++]]=k)
28         for(k=k?k-1:k,j=sa[rnk[i]-1];s[i+k]==s[j+k];k++);
29     }
30 }
31 using namespace suffixarray;
32
33 int n,q;
34 ll k,sum[N],L,R;
35
36 int a[N][18],b[N][18];
37 void rmq(int *a,int f[][18])
38 {
39     for(int i=1;i<=n;i++)f[i][0]=a[i];
40     for(int j=1;1<<j<n;j++)for(int i=1;i<=n;i++)
41     if(i+(1<<j)-1<= n)f[i][j]=min(f[i][j-1],f[i+(1<<j-1)][j-1]);
42     else break;
43 }
44 inline int find(int l,int r,int f[][18])
45 {
46     int k=31-__builtin_clz(r-l+1);
47     return min(f[l][k],f[r-(1<<k)+1][k]);
48 }
49
50 void getkth(ll k)
51 {
52     if(k>sum[n]){L=R=0;return;}
53     int l=0,r=n,ans,mid;
54     while(l<=r)
55     {
56         mid=l+r>>1;
57         if(sum[mid]>=k)ans=mid,r=mid-1;
58         else l=mid+1;
59     }
60     k=k-sum[ans-1]+height[ans];
61     int pos=ans;
62     l=2,r=n-pos+1,ans=1;
63     while(l<=r)
64     {
65         mid=l+r>>1;
66         if(find(pos+1,pos+mid-1,a)>=k)l=mid+1,ans=mid;
67         else r=mid-1;
68     }
69     L=find(pos,pos+ans-1,b)+1,R=L+k-1;
70 }
71
72 int main(){
73     while(~scanf("%s",s))
74     {
75         L=R=0,getsa((n=strlen(s))+1,150);
76         F(i,1,n)sum[i]=n-sa[i]-height[i]+sum[i-1];
77         rmq(height,a),rmq(sa,b);
78         scanf("%d",&q);
79         while(q--)
80         {
81             scanf("%lld",&k);
82             k=(k^L^R)+1,getkth(k);
83             printf("%lld %lld\n",L,R);
84         }
85     }
86     return 0;
87 }

View Code

转载于:https://www.cnblogs.com/bin-gege/p/7510693.html

hdu 5008 Boring String Problem(后缀数组+rmq)相关推荐

  1. HDU 5008 Boring String Problem ( 后缀数组求本质不同第k大子串)

    Boring String Problem Zeronera题解 预处理sum数组记录不同字符串的个数,即sum[i] = n- sa[i] + 1 -height[i] + sum[i-1] (n为 ...

  2. HDU - 5008 Boring String Problem(后缀数组+二分)

    题目链接:点击查看 题目大意:给出一个字符串,接下来给出 q 个询问,每次询问字符串中第 k 大的子串,要求输出该字串的左右端点,如果有多个答案,输出左端点最小的一个 题目分析:因为在求出后缀数组后, ...

  3. HDU - 5008 Boring String Problem(后缀树求本质不同第k大子串)

    题目链接:点击查看 题目大意:给出一个长度为 nnn 的字符串,再给出 mmm 次询问,每次询问需要输出本质不同第 kkk 小的子串的起止位置.如果有多个答案,输出起点最小的那个.强制在线. 题目分析 ...

  4. HDU - 4552 怪盗基德的挑战书(后缀数组+RMQ/KMP+dp)

    题目链接:点击查看 题目大意:给出一个字符串,统计每个前缀在字符串中出现的次数之和 题目分析:可以直接先用后缀数组跑出来height,再用RMQ跑出来任意两个后缀的height,我们可以将题意转换为求 ...

  5. 【uva10829-求形如UVU的串的个数】后缀数组+rmq or 直接for水过

    题意:UVU形式的串的个数,V的长度规定,U要一样,位置不同即为不同字串 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&am ...

  6. HDU - 6194 string string string(后缀数组+RMQ+容斥)

    题目链接:点击查看 题目大意:给出一个字符串和一个数字 k,问字符串中出现次数恰好等于 k 次的字串有多少个 题目分析:在跑完后缀数组后,我们可以用sa数组求解,具体做法是枚举起点,找长度为 k 的s ...

  7. HDU 6194 string string string 后缀数组 + RMQ(线段树)

    传送门:HDU6194 题意:问给定字符串中有多少种出现k次的子串. 思路:首先想到后缀数组经典问题,求出现不少于k次的子串的最大长度,类似的这题肯定就是在height数组上搞事情啦. 将height ...

  8. hdu 2459 (后缀数组+RMQ)

    题意:让你求一个串中连续重复次数最多的串(不重叠),如果重复的次数一样多的话就输出字典序小的那一串. 分析:有一道比这个简单一些的题spoj 687, 假设一个长度为l的子串重复出现两次,那么它必然会 ...

  9. HDU 6194 String String String (后缀数组+线段树, 2017 ACM/ICPC Asia Regional Shenyang Online)

    Problem 求字符串 S 中严格出现 k 次的子串个数 k≥1k\ge 1 |S|≤105|S|\le 10^5 ∑|S|≤2×106\sum |S| \le 2\times 10^6 Idea ...

最新文章

  1. 别把引擎当汽车:AutoML不值得……
  2. 实用PS技巧分享,送给初入职场的你
  3. android intent传递数据
  4. 浅析二层工业交换机的特点
  5. Python(20)-高级数据类型的公共方法
  6. 计算机组成原理「一」计算机系统概述
  7. Java中List,ArrayList、Vector,map,HashTable,HashMap区别用法
  8. Dymola — 多学科系统仿真平台
  9. Java中jdk安装与环境变量配置
  10. 鄙视那些把爬虫当作AI的SB,清华学霸尹成大哥的历史上最强大的爬虫视频
  11. Windows 制作免安装的JAVA环境
  12. LiveNVR监控流媒体Onvif/RTSP功能-Onvif 发现以及探测通过ONVIF添加摄像头监控直播及云台控制
  13. 漏刻有时云守护数据可视化画质感知状态迭代说明文档
  14. PCB拼板设计对SMT生产效率到底有多大的影响?
  15. pion:rtc-to-webrtc示例
  16. css文字中间省略号使用js实现
  17. 关于使用mysqlworkbench实现远程连接数据库
  18. 软考知识点笔记之----制订项目管理计划
  19. css水平垂直居中各种方法实现方式
  20. 六、Spring Boot整合Shiro

热门文章

  1. linux 优雅重启进程,apache2 重启、停止、优雅重启、优雅停止
  2. php 微信定位,微信企业号(服务号)坐标定位发生偏移解决方案记录( 附PHP代码)...
  3. 网格自适应_Abaqus网格重划自适应技术
  4. cmap参数 plt_Matplotlib入门-5-plt.scatter( )绘制散点图
  5. 运营私域流量转化没效果为什么?
  6. EA与Rose UML建模工具比较
  7. IIS下配置php运行环境
  8. #,#x,\u开头的unicode介绍
  9. elasticsearch 查询数据 | 分页查询
  10. xgboost相比传统gbdt有何不同?xgboost为什么快?xgboost如何支持并行?