题目

传送门 to DarkBZOJ

思路

首先有这样一个事实,如果两个字符串 a , b a,b a,b 满足 a < b a<b a<b ,那么二者的相同长度的前缀 a ′ , b ′ a',b' a′,b′ 满足 a ′ ≤ b ′ a'\le b' a′≤b′ 。这是显而易见的。同时,如果这个长度超过了二者的 l c p lcp lcp ,还会有 a ≤ b ′ a\le b' a≤b′ 。

另一个事实是前缀小于原串,也就是 a ′ ≤ a a'\le a a′≤a ,这也是毋庸置疑的。所以,如果长度超过 l c p lcp lcp ,我们有

a ′ ≤ a < b ′ ≤ b a'\le a<b'\le b a′≤a<b′≤b

那么我们先二分一个后缀,让大于这个后缀的都滚蛋。字典序比它小的后缀,肯定始终比它小;字典序比它大的,不能留下超过 l c p lcp lcp 的长度。所以我们会得到一些区间,限制条件是区间内至少切一刀。

怎么实现 “ 区间内至少切一刀 ” 的条件呢?这种题大家想必做的很多了,就是贪心,按照右端点排序,而后从左往右填。说白了就是,只有不得不切的时候才切。在本题中就比较容易实现。

所以我们找到一个字典序最小的后缀 a a a 使得最终答案不超过 a a a 。假设最终的答案是后缀 b ( b ≠ a ) b(b\ne a) b(b​=a) 的一个前缀,那么 b > a b>a b>a ,否则 b b b 才是应当被找到的后缀。

如果这个前缀的长度超过 l c p ( a , b ) lcp(a,b) lcp(a,b) ,那么根据上面的结论有 a < b ′ a<b' a<b′ ,显然不成立(答案是不超过 a a a 的);所以其长度不超过 l c p ( a , b ) lcp(a,b) lcp(a,b) 。你惊讶地发现:它也是 a a a 的一个前缀

所以答案一定是 a a a 的前缀。二分即可,越长的前缀字典序越大。还是利用上面的不等式进行判断。

复杂度 O ( n log ⁡ n ) \mathcal O(n\log n) O(nlogn) ,用 S A \tt SA SA 即可。

代码

#include <cstdio>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long int_;
inline int readint(){int a = 0; char c = getchar(), f = 1;for(; c<'0'||c>'9'; c=getchar())if(c == '-') f = -f;for(; '0'<=c&&c<='9'; c=getchar())a = (a<<3)+(a<<1)+(c^48);return a*f;
}const int MaxN = 200010;int sa[MaxN], rnk[MaxN<<1];
int tmp[MaxN<<1], buck[MaxN];
void prepare(int n,int m){memset(buck,0,m<<2);for(int i=0; i<n; ++i)++ buck[rnk[i]];for(int i=1; i<m; ++i)buck[i] += buck[i-1];
}
# define XEZ(x) sa[-- buck[rnk[x]]] = x
/** @brief from index 0 to @p n-1 */
void getSA(int a[],int n){memset(tmp+n,-1,n<<2); // EOFmemset(rnk+n,-1,n<<2); // EOFmemcpy(tmp,a,n<<2);sort(tmp,tmp+n); // to hashint m = unique(tmp,tmp+n)-tmp;for(int i=0; i<n; ++i)rnk[i] = lower_bound(tmp,tmp+m,a[i])-tmp;prepare(n,m);for(int i=0; i<n; ++i) XEZ(i);for(int w=1,p; m!=n; w<<=1,m=p+1){for(int i=n-w+(p=0); i<n; ++i)tmp[p ++] = i; // indexfor(int i=0; i<n; ++i)if(sa[i] >= w)tmp[p ++] = sa[i]-w;prepare(n,m);for(int i=n-1; ~i; --i)XEZ(tmp[i]); // big firstmemcpy(tmp,rnk,n<<2);rnk[sa[0]] = p = 0;for(int i=1; i<n; ++i){if(tmp[sa[i]] != tmp[sa[i-1]]||tmp[sa[i]+w] != tmp[sa[i-1]+w])++ p; // brand new onernk[sa[i]] = p;}}
}int heit[MaxN]; // height
void getHei(int a[],int n){for(int i=0,j,k=0; i<n; ++i)if(rnk[i] == 0)heit[0] = k = 0;else{if(k) -- k;j = sa[rnk[i]-1];while(max(i,j)+k <= n&& a[j+k] == a[i+k])++ k; // k = lenheit[rnk[i]] = k;}
}namespace RMQ{int st[20][MaxN], *item;int xez[MaxN]; // log2void prepare(int a[],int n){xez[0] = -1;for(int i=0; i<n; ++i)st[0][i] = i;for(int i=1; i<=n; ++i)xez[i] = xez[i>>1]+1;item = a; // copy itfor(int j=0; (2<<j)<=n; ++j)for(int i=0; i+(2<<j)<=n; ++i){st[j+1][i] = st[j][i+(1<<j)];if(a[st[j+1][i]] > a[st[j][i]])st[j+1][i] = st[j][i];}}int query(int l,int r){int k = xez[r-l+1];r = st[k][r-(1<<k)+1];if(item[r] < item[st[k][l]])return r; // minimumreturn st[k][l];}
}char wyl[MaxN]; int xyx[MaxN];int main(){//  freopen("4310\\2.in","r",stdin);
//  freopen("xez.out","w",stdout);int k = readint();scanf("%s",wyl);int n = strlen(wyl);for(int i=0; i<n; ++i)xyx[i] = wyl[i];getSA(xyx,n), getHei(xyx,n);RMQ::prepare(heit,n);int L = 0, R = n-1; // ErFenfor(int mid=(L+R)>>1; L!=R; mid=(L+R)>>1){int cnt = 0, now = n; // cut timefor(int i=0; i<n&&cnt<k; ++i){if(rnk[i] > mid){int x = RMQ::query(mid+1,rnk[i]);if(heit[x] == 0) cnt = k;now = min(now,i+heit[x]-1);}if(i == now) // it's a must++ cnt, now = n;}if(now != n) ++ cnt;if(cnt < k) // it's fineR = mid; // it can be smallerelse L = mid+1; // not OK}int id = sa[L]; // which suf
//  printf("id = %d, suf = ",id);
//  puts(wyl+id);L = heit[rnk[id]]+1, R = n-id; // length
//  printf("BiSearch %d %d\n",L,R);for(int mid=(L+R)>>1; L!=R; mid=(L+R)>>1){int cnt = 0, now = n;for(int i=0; i<n&&cnt<k; ++i){if(rnk[i] > rnk[id]){int x = RMQ::query(rnk[id]+1,rnk[i]);x = min(heit[x],mid);if(x == 0) cnt = k;now = min(now,i+x-1);}else if(i == id)now = min(now,i+mid-1);if(i == now) ++ cnt, now = n;}if(now != n) ++ cnt;if(cnt < k) R = mid;else L = mid+1; // cannot}for(int i=id; i<id+L; ++i)putchar(wyl[i]);putchar('\n');return 0;
}

[DarkBZOJ4310]跳蚤相关推荐

  1. POJ 1091 跳蚤

    跳蚤 Time Limit: 1000ms Memory Limit: 10000KB This problem will be judged on PKU. Original ID: 1091 64 ...

  2. P2231 [HNOI2002]跳蚤(裴蜀定理/莫比乌斯反演)

    P2231 [HNOI2002]跳蚤 给定一个长度为n+1的一列数,第n+1位为m,前n位小于m 求解使得他n+1个数的加减可以凑出1的方案数 首先可以凑出1,这显然是裴蜀定理,推一推就发现他要求所有 ...

  3. [LOJ 6042]「雅礼集训 2017 Day7」跳蚤王国的宰相(树的重心+贪心)

    [LOJ 6042]「雅礼集训 2017 Day7」跳蚤王国的宰相 description solution 一个到所有节点距离和最小的节点 ⇔\Leftrightarrow⇔ 树的重心(满足最重的儿 ...

  4. 毕业设计上线啦!----跳蚤部落与基于Comet的WebIM系统开发

    我不清楚把我的毕业设计的东西放上来之后,毕业论文答辩的时候会不会说我是在网上抄袭的,不过我还是果断的发上来与大家分享了!!呵呵,请大家支持!高手就绕道吧! 现在已经放到公网上,并且开始使用,兼容IE6 ...

  5. 跳蚤(POJ-1091)

    Problem Description Z城市居住着很多只跳蚤.在Z城市周六生活频道有一个娱乐节目.一只跳蚤将被请上一个高空钢丝的正中央.钢丝很长,可以看作是无限长.节目主持人会给该跳蚤发一张卡片.卡 ...

  6. poj1091:跳蚤【容斥原理】

    题目大意:中文题就不翻译了 思路:假设跳蚤选择X1个第一张卡片,X2个第二张卡片...Xn个第n张卡片,Xn+1张写着m的卡片,那么就可以列出方程:a1*X1+a2*X2+-+an*Xn+m*X(n+ ...

  7. springboot毕设项目线上跳蚤市场平台iy7e7(java+VUE+Mybatis+Maven+Mysql)

    springboot毕设项目线上跳蚤市场平台iy7e7(java+VUE+Mybatis+Maven+Mysql) 项目运行 环境配置: Jdk1.8 + Tomcat8.5 + Mysql + HB ...

  8. 哲理小故事--跳蚤人生

    有人曾经做过这样一个实验:他往一个玻璃杯里放进一只跳蚤,发现跳蚤立即轻易地跳了出来.再重复几遍,结果还是一样.根据测试,跳蚤跳的高度一般可达它身体高度的400倍左右,所以说跳蚤可以称得上是动物界的跳高 ...

  9. 校园跳蚤市场平台/校园二手交易平台管理系统

    摘  要 本文论述了校园跳蚤市场平台的设计和实现,该网站从实际运用的角度出发,运用了计算机网站设计.数据库等相关知识,网络和Mysql数据库设计来实现的,网站主要包括学生注册.学生登录.浏览商品.搜索 ...

最新文章

  1. Word 2003文件保存和另存为操作是否熟练掌握的有关测试
  2. 多媒体流信息提取工具 ffprobe 简介
  3. Ubuntu Server 上在安装Nginx时执行./confgiure后提示:C compiler cc is not found
  4. gj6 深入python的set和dict
  5. Exchange 2013 OWA重定向
  6. r3 4300u r5 u_R5刀粒
  7. POJ-1260 Pearls---DP
  8. .mysql的配置文件是正确的,为啥启动后一查所展示的并不是自己设置的配置
  9. 智能灯控制页面用HTML编写,一种基于STM32的智能灯控制系统的制作方法
  10. [工作习惯]一种管理文献的方法,抛弃EndNote
  11. 细胞分裂题--递归算法
  12. Mysql,姓名按笔画排序
  13. html5中国产业联盟,中软国际联合发起HTML5+联盟为产业生态服务
  14. Python 数据相关性分析
  15. 《你坏-大冰》阅读笔记
  16. 机器学习服务活体检测算法荣获CFCA权威安全认证
  17. 安恒2018.10 level1思路讲解
  18. zkh工业/润滑油//服// 务
  19. 2014年节假日放假方案发布,全年假期依然维持11天不变
  20. 根据经纬度信息画实际地图中的轨迹之百度地图与谷歌地球

热门文章

  1. 鸿蒙系统安兔兔评测,跑分对比/总结
  2. [微信开发] 微信公众号被关注后如何回复多条消息?
  3. Pandas教程【国宝级教程,一万八千字总结】
  4. 科大晋校第四次周训(C语言网)
  5. 【uni-app基础教程】
  6. Chevereto-搭建一个自己的图床
  7. 直线的倾斜角斜率和直线方程
  8. 【更新】LMD VCL Complete 2019.1发布
  9. mysql的正确发音
  10. KUKA机器人通过EthernetKRL控制