思路:

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

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

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

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

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

From Dad3zZ

//By SiriusRen
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=100050;
typedef long long ll;
int n,k,cntA[N],cntB[N],A[N],B[N],sa[N],tsa[N],rk[N],ht[N],Log[N],st[N][20];
int L,R;ll l,r,ans;
char s[N];
void SA(){for(int i=1;i<=n;i++)cntA[s[i]]++;for(int i=1;i<=256;i++)cntA[i]+=cntA[i-1];for(int i=n;i;i--)sa[cntA[s[i]]--]=i;rk[sa[1]]=1;for(int i=2;i<=n;i++)rk[sa[i]]=rk[sa[i-1]]+(s[sa[i]]!=s[sa[i-1]]);for(int l=1;rk[sa[n]]<n;l<<=1){memset(cntA,0,sizeof(cntA));memset(cntB,0,sizeof(cntB));for(int i=1;i<=n;i++)cntA[A[i]=rk[i]]++,cntB[B[i]=i+l<=n?rk[i+l]:0]++;for(int i=1;i<=n;i++)cntA[i]+=cntA[i-1],cntB[i]+=cntB[i-1];for(int i=n;i;i--)tsa[cntB[B[i]]--]=i;for(int i=n;i;i--)sa[cntA[A[tsa[i]]]--]=tsa[i];rk[sa[1]]=1;for(int i=2;i<=n;i++)rk[sa[i]]=rk[sa[i-1]]+(A[sa[i]]!=A[sa[i-1]]||B[sa[i]]!=B[sa[i-1]]);}for(int i=1,j=0;i<=n;i++){j=j?j-1:0,Log[i]=i!=1?Log[i>>1]+1:0;while(s[i+j]==s[sa[rk[i]-1]+j])j++;st[rk[i]][0]=ht[rk[i]]=j;}for(int j=1;j<=19;j++)for(int i=1;i+(1<<(j-1))<=n;i++)st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
}
int lcp(int x,int y){if(x==y)return n-x+1;x=rk[x],y=rk[y];if(x>y)swap(x,y);x++;int t=Log[y-x+1];return min(st[x][t],st[y-(1<<t)+1][t]);
}
void get(ll k){for(int i=1;i<=n;i++){if(n-sa[i]-ht[i]+1<k)k=k-(n-sa[i]-ht[i]+1);else{L=sa[i],R=sa[i]+ht[i]+k-1;break;}}
}
bool cmp(int l1,int r1,int l2,int r2){int len1=r1-l1+1,len2=r2-l2+1,LCP=lcp(l1,l2);if(len1<=len2&&LCP>=len1)return 1;if(len1>len2&&LCP>=len2)return 0;if(LCP>=len1&&LCP>=len2)return len1<len2;return s[l1+LCP]<s[l2+LCP];
}
bool check(){int cnt=1,last=n;for(int i=n;i;i--){if(!cmp(i,last,L,R))cnt++,last=i;if(cnt>k)return 0;}return 1;
}
int main(){scanf("%d%s",&k,s+1),n=strlen(s+1),SA();for(int i=1;i<=n;i++)r+=n-sa[i]-ht[i]+1;while(l<=r){ll mid=(l+r)>>1;get(mid);if(check())r=mid-1,ans=mid;else l=mid+1;}get(ans);s[R+1]=0;printf("%s\n",s+L);
}

转载于:https://www.cnblogs.com/SiriusRen/p/6685548.html

BZOJ 4310 二分+SA+RMQ相关推荐

  1. YbtOJ-相似子串【SA,RMQ,二分】

    正题 题目大意 给出一个长度为nnn的字符串,两个串相似当且仅当可以通过每种字符置换使得它们相同. qqq次询问这个字符串所有子串中和这个串中sl,rs_{l,r}sl,r​子串有多少个相似的. 1≤ ...

  2. BZOJ 4892: [Tjoi2017]DNA(SA+RMQ / SAM)

    Description 加里敦大学的生物研究所,发现了决定人喜不喜欢吃藕的基因序列S,有这个序列的碱基序列就会表现出喜欢吃藕的 性状,但是研究人员发现对碱基序列S,任意修改其中不超过3个碱基,依然能够 ...

  3. [2020.11.26NOIP模拟赛]勇者的后缀【SA,RMQ,主席树,二分】

    正题 题目链接:https://www.luogu.com.cn/problem/U142356?contestId=37784 题目大意 一个字符串,询问给出(x,l,r)(x,l,r)(x,l,r ...

  4. 【SPOJ1297】Palindrome (SA+RMQ)

    求最长回文串.把原串翻转后,加在原串后面,中间插入一个辨别字符.然后求SA,Height.然后枚举每个字母作为回文串中心,分长度为奇数和偶数去讨论:奇数求 suffix(i)和suffix(n-i+1 ...

  5. Hdoj 3486 Interviewer(二分加RMQ)

    题目传送门 //解题思路:利用st算法预处理出区间最值,然后二分当前的组数,因为组数越多选的人越多,得到的能力值也就越高,因为每个区间变大,很可能覆盖掉之前的最大值,很可能扩大的区间覆盖掉了之前的最大 ...

  6. bzoj 1863 二分+dp check

    思路:二分之后用dp去check就好啦. #include<bits/stdc++.h> #define LL long long #define fi first #define se ...

  7. BZOJ 3489: A simple rmq problem

    3489: A simple rmq problem Time Limit: 40 Sec  Memory Limit: 600 MB Submit: 1594  Solved: 520 [Submi ...

  8. BZOJ 1305 二分+网络流

    思路: 建图我根本没有想到啊--. (我是不会告诉你我借鉴了一下题解的思路) 把每个人拆成喜欢的和不喜欢的点 男 喜欢 向 男 不喜欢 连 边权为k的边 如果男喜欢女 那么 男喜欢向 女喜欢 连 1 ...

  9. BZOJ 4753 二分+树形DP

    思路: 先二分答案 f[x][j]表示在x的子树里选j个点 f[x][j+k]=max(f[x][j+k],f[x][j]+f[v[i]][k]); 初始化 x!=0 -> f[x][1]=p[ ...

最新文章

  1. linux中yum进程占cpu百分之九十,在Deepin Linux系统中kworker进程占用CPU达到100%的解决...
  2. gunicorn多进程不死_WEB,gunicorn - 无论是多进程、多线程、协程模式,同一个浏览器窗口多个标签页访问同一个url,看上去不会并发的问题...
  3. domains where phd is best in business school
  4. 利用ABAP 740的新关键字REDUCE完成一个实际工作任务
  5. 论调用约定__stdcall,__cdecl,__fastcall,thiscall,naked call
  6. DOM事件与jQuery事件的是非纠葛
  7. Qt工作笔记-Qt生成dll或so,并且调用(含Liunx端与Windows端)
  8. P2:图像分类:KNN与线性分类器
  9. React Native vs. Cordova.
  10. matlab如何求解定积分,matlab如何求解定积分
  11. 高频故障-桌面图标变成白纸图标的恢复方案
  12. 一键端服务器维护,游戏服务器一键端
  13. Cesium 中的离屏渲染
  14. 静态库(lib)和动态库(dll)的使用
  15. k8spod资源的基础管理操作
  16. 如何提高网站关键词排名和增加收录量
  17. 郭台铭为什么如此有魄力?
  18. 4位BCD计数器Verillog简便代码-无需例化子模块
  19. PMP备考大全:经典题库(敏捷管理第5期)
  20. 解决ios与安卓兼容问题 --- css

热门文章

  1. list 转换成datatable
  2. append,appendTo和prepend
  3. redis远程链接(NOAUTH Authentication required)
  4. 软件测试基础 - 系统测试
  5. python01_Python编码环境安装与基本语法
  6. php限制接口访问次数_令牌桶限流思路分享(PHP+Redis实现机制)
  7. python遍历数组冒泡排序_Python算法(一) 数组冒泡排序(难度等级:easy)
  8. HTML5新增相关标签的和属性
  9. python神奇时钟项目_怎么在Python项目中利用Pygame绘制一个时钟
  10. 分段函数怎么用神经网络进行拟合_Tensoflow简单神经网络实现非线性拟合