4310: 跳蚤

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit:
180  Solved: 83
[Submit][Status][Discuss]

Description

很久很久以前,森林里住着一群跳蚤。一天,跳蚤国王得到了一个神秘的字符串,它想进行研究。
首先,他会把串分成不超过 k 个子串,然后对于每个子串 S,他会从S的所有子串中选择字典序最大的那一个,并在选出来的 k
个子串中选择字典序最大的那一个。他称其为“魔力串”。
现在他想找一个最优的分法让“魔力串”字典序最小。

Input

第一行一个整数 k。
接下来一个长度不超过 105 的字符串

Output

输出一行,表示字典序最小的“魔力串”。

Sample Input

13
bcbcbacbbbbbabbacbcbacbbababaabbbaabacacbbbccaccbcaabcacbacbcabaacbccbbcbcbacccbcccbbcaacabacaaaaaba

Sample Output

cbc

HINT

S的长度<=100000

Source

Solution

首先求出后缀数组和height数组,这样能得到本质不同的子串数目

这里利用:本质不同的子串$=\sum(Len-SA[i]-height[i])$利用SA[],height[]的定义很好想

然后要求最大值最小,显然二分,二分一个mid,求出第mid大的子串

然后贪心的检验,从后往前扫,当字典序超过二分的值时,划分一下,看划分个数与K的关系即可

中间涉及比较,用LCP实现即可,显然ST表非常方便

Code

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cstring>
  4. using namespace std;
  5. #define maxn 1000100
  6. char S[maxn]; int SA[maxn],len,K;
  7. int wa[maxn],wb[maxn],ws[maxn],wv[maxn];
  8. long long tot;
  9. int L,R;
  10. inline int cmp(int *r,int a,int b,int l)
  11. {
  12. return r[a]==r[b]&&r[a+l]==r[b+l];
  13. }
  14. inline void DA(char *r,int *sa,int n,int m)
  15. {
  16. int p,*x=wa,*y=wb,*t;
  17. for (int i=; i<m; i++) ws[i]=;
  18. for (int i=; i<n; i++) ws[x[i]=r[i]]++;
  19. for (int i=; i<m; i++) ws[i]+=ws[i-];
  20. for (int i=n-; i>=; i--) sa[--ws[x[i]]]=i;
  21. p=; for (int j=; p<n; j*=,m=p)
  22. {
  23. p=; for (int i=n-j; i<n; i++) y[p++]=i;
  24. for (int i=; i<n; i++) if (sa[i]>=j) y[p++]=sa[i]-j;
  25. for (int i=; i<n; i++) wv[i]=x[y[i]];
  26. for (int i=; i<m; i++) ws[i]=;
  27. for (int i=; i<n; i++) ws[wv[i]]++;
  28. for (int i=; i<m; i++) ws[i]+=ws[i-];
  29. for (int i=n-; i>=; i--) sa[--ws[wv[i]]]=y[i];
  30. t=x,x=y,y=t;p=;x[sa[]]=;
  31. for (int i=; i<n; i++)
  32. x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
  33. }
  34. }
  35. int rank[maxn],height[maxn];
  36. inline void calheight(char *r,int *sa,int n)
  37. {
  38. int k=;
  39. for (int i=; i<=n; i++) rank[sa[i]]=i;
  40. for (int i=; i<n; height[rank[i++]]=k)
  41. {k?k--:;for (int j=sa[rank[i]-]; r[i+k]==r[j+k]; k++);}
  42. }
  43. int log2[maxn]; int dp[maxn][];
  44. void ST(int n)
  45. {
  46. log2[]=-;
  47. for (int i=; i<=n; i++)
  48. if (i&(i-)) log2[i]=log2[i-];
  49. else log2[i]=log2[i-]+;
  50. for (int i=; i<=n; i++) dp[i][]=height[i];
  51. for (int j=; (<<j)<=len; j++)
  52. for (int i=; i+(<<j)-<=n; i++)
  53. dp[i][j]=min(dp[i][j-],dp[i+(<<(j-))][j-]);
  54. }
  55. int RMQ(int l,int r)
  56. {
  57. int tmp=log2[r-l+];
  58. return min(dp[l][tmp],dp[r-(<<tmp)+][tmp]);
  59. }
  60. int LCP(int l,int r)
  61. {
  62. if (l==r) return len-l;
  63. l=rank[l]; r=rank[r];
  64. if (l>r) swap(l,r); l++;
  65. return RMQ(l,r);
  66. }
  67. void Get(long long k)
  68. {
  69. for (int i=; i<=len; i++)
  70. if ((long long)(len-SA[i]-height[i])<k) k-=(long long)(len-SA[i]-height[i]);
  71. else {L=SA[i],R=SA[i]+height[i]+k-; break;}
  72. }
  73. bool Compare(int l1,int r1,int l2,int r2)
  74. {
  75. int len1=r1-l1+,len2=r2-l2+,lcp=LCP(l1,l2);
  76. if (len1<=len2 && lcp>=len1) return ;
  77. if (len1>len2 && lcp>=len2) return ;
  78. if (lcp>=len1 && lcp>=len2) return len1>len2? :;
  79. return S[l1+lcp]>S[l2+lcp]? :;
  80. }
  81. int Check()
  82. {
  83. int cnt=,last=len-;
  84. for (int i=len-; i>=; i--)
  85. {
  86. if (S[i]>S[L]) return ;
  87. if (!Compare(i,last,L,R)) ++cnt,last=i;
  88. if (cnt>K) return ;
  89. }
  90. return ;
  91. }
  92. int main()
  93. {
  94. scanf("%d",&K); scanf("%s",S);
  95. len=strlen(S); S[len]=;
  96. DA(S,SA,len+,); calheight(S,SA,len);
  97. ST(len);
  98. for (int i=; i<=len; i++) tot+=len-SA[i]-height[i];
  99. // printf("%d\n",tot);
  100. long long l=,r=tot;
  101. while (l<=r)
  102. {
  103. long long mid=(l+r)>>;
  104. Get(mid);
  105. // printf("L=%d R=%d\n",L,R);
  106. if (Check()) r=mid-; else l=mid+;
  107. // printf("%I64d %I64d\n",l,r);
  108. }
  109. Get(r+);
  110. for (int i=L; i<=R; i++) putchar(S[i]);
  111. return ;
  112. }

【BZOJ-4310】跳蚤 后缀数组 + ST表 + 二分的更多相关文章

  1. 2019CCPC网络赛 C - K-th occurrence HDU - 6704(后缀数组+ST表+二分+主席树)

    题意 求区间l,r的子串在原串中第k次出现的位置. 链接:https://vjudge.net/contest/322094#problem/C 思路 比赛的时候用后缀自动机写的,TLE到比赛结束. ...

  2. bzoj 4310: 跳蚤【后缀数组+st表+二分+贪心】

    先求一下SA 本质不同的子串个数是\( \sum n-sa[i]+1-he[i] \),按字典序二分子串,判断的时候贪心,也就是从后往前扫字符串,如果当前子串串字典序大于二分的mid子串就切一下,然后 ...

  3. bzoj 4310 跳蚤 —— 后缀数组+二分答案+贪心

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4310 二分答案——在本质不同的子串中二分答案! 如果二分到的子串位置是 st,考虑何时必须分 ...

  4. bzoj 4310 跳蚤——后缀数组+二分答案+贪心

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4310 答案有单调性? 二分出来一个子串,判断的时候需要满足那些字典序比它大的子串都不出现! ...

  5. SPOJ 687 Repeats(后缀数组+ST表)

    [题目链接] http://www.spoj.com/problems/REPEATS/en/ [题目大意] 求重复次数最多的连续重复子串的长度. [题解] 考虑错位匹配,设重复部分长度为l,记s[i ...

  6. POJ 3693 Maximum repetition substring(后缀数组+ST表)

    [题目链接] poj.org/problem?id=3693 [题目大意] 求一个串重复次数最多的连续重复子串并输出,要求字典序最小. [题解] 考虑错位匹配,设重复部分长度为l,记s[i]和s[i+ ...

  7. BZOJ_4516_[Sdoi2016]生成魔咒_后缀数组+ST表+splay

    BZOJ_4516_[Sdoi2016]生成魔咒_后缀数组+ST表+splay Description 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1.2 拼凑起来形成一个魔 ...

  8. UVA10829 L-Gap Substrings(后缀数组+ST表)

    后缀数组+ST表. 代填的坑. \(Code\ Below:\) #include <bits/stdc++.h> #define ll long long using namespace ...

  9. BZOJ 4556 [Tjoi2016&Heoi2016]字符串 ——后缀数组 ST表 主席树 二分答案

    Solution 1: 后缀数组暴力大法好 #include <map> #include <cmath> #include <queue> #include &l ...

随机推荐

  1. PHP代码20个实用技巧(转)

    这些技巧特别是封装的,相对路径的还是挺好的,本身来自微信公众号,但是我担心以后删除,所以在我的博客上备份一下(微信公众号为:菜鸟教程) 在这篇文章中我们将看看一些关于PHP开发有用的提示和技巧,可以用 ...

  2. jQuery EasyUI 1.3.4 API CHM版下载

    网盘下载

  3. 眼保Guide

    1.睡前不要玩手机,特别是关灯玩手机!否则第二天早上你就会感到眼睛模糊了.长久下去就会形成近视或者近视加深. 2.早上起床半小时内不要戴眼镜,不要看手机.电脑等一切电子屏幕,甚至不要看书.这段时间是眼 ...

  4. C# 7.0 新特性1: 基于Tuple的“多”返回值方法

    本文基于Roslyn项目中的Issue:#347 展开讨论. 1. C# 7.0 新特性1: 基于Tuple的“多”返回值方法 2. C# 7.0 新特性2: 本地方法 3. C# 7.0 新特性3: ...

  5. 转载:ZooKeeper Programmer's Guide(中文翻译)

    本文是为想要创建使用ZooKeeper协调服务优势的分布式应用的开发者准备的.本文包含理论信息和实践信息. 本指南的前四节对各种ZooKeeper概念进行较高层次的讨论.这些概念对于理解ZooKeep ...

  6. C#访问Azure的资源

    官方参考资料在这里:https://msdn.microsoft.com/en-us/library/azure/dn722415.aspx,本文放一些重点及遇到的坑的解决办法. 身份验证 不是说,我 ...

  7. js下拉框

    Js下拉框   http://sc.chinaz.com/tag_jiaoben/XiaLaKuang.html

  8. js的一些冷门的用法

    1.delete 2.void 0 3.>>> 4.>>0 字符串转为数字 5.[] == ![] 6.

  9. [BZOJ3156]防御准备(斜率优化DP)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3156 分析: 简单的斜率优化DP

  10. yii2搭建完美后台并实现rbac权限控制实例教程

    1.安装yii2 未安装的请参考yii2史上最简单式安装教程,没有之一 或者参考yii2实战教程之详细安装步骤 已安装的请继续看下一步操作 2.配置数据库 2.1 配置数据库 修改common/con ...