题意:

n<=1e5

思路:

From http://hzwer.com/6152.html

往后匹配多远 r 用ST表求lcp即可。。。往前 l 就把串反过来再做一下。。

但是有可能求出来的最长串可以前移/后移几位
即开头可以在落在[i−l,i−l+(l+r)mod L]

区间内字典序最小的还要用ST表找rank区间最值

有空需要学习一下结构体写法 一模一样的东西写多次太累了

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<string>
  4. #include<cmath>
  5. #include<iostream>
  6. #include<algorithm>
  7. #include<map>
  8. #include<set>
  9. #include<queue>
  10. #include<vector>
  11. using namespace std;
  12. typedef long long ll;
  13. typedef unsigned int uint;
  14. typedef unsigned long long ull;
  15. typedef pair<int,int> PII;
  16. typedef vector<int> VI;
  17. #define fi first
  18. #define se second
  19. #define MP make_pair
  20. #define N 110000
  21. #define MOD 1000000007
  22. #define eps 1e-8
  23. #define pi acos(-1)
  24. #define oo 1000000000
  25.  
  26. char ch[N];
  27. int n,i,s[N],sa[N],wa[N],wb[N],wc[N],wd[N],height[N],rank[N],
  28. ans,mx,ansl,ansr,f[][N][],g[][N],save[N],Log[N],bin[N];
  29.  
  30. int read()
  31. {
  32. int v=,f=;
  33. char c=getchar();
  34. while(c<||<c) {if(c=='-') f=-; c=getchar();}
  35. while(<=c&&c<=) v=(v<<)+v+v+c-,c=getchar();
  36. return v*f;
  37. }
  38.  
  39. bool cmp(int *r,int a,int b,int l)
  40. {
  41. return r[a]==r[b]&&r[a+l]==r[b+l];
  42. }
  43.  
  44. void getsa(int *r,int *sa,int n,int m)
  45. {
  46. int *x=wa,*y=wb,j,p;
  47. for(i=;i<n;i++) wc[x[i]=r[i]]++;
  48. for(i=;i<m;i++) wc[i]+=wc[i-];
  49. for(i=n-;i>=;i--) sa[--wc[x[i]]]=i;
  50. for(j=,p=;p<n;j*=,m=p)
  51. {
  52. p=;
  53. for(i=n-j;i<n;i++) y[p++]=i;
  54. for(i=;i<n;i++)
  55. if(sa[i]>=j) y[p++]=sa[i]-j;
  56. for(i=;i<n;i++) wd[i]=x[y[i]];
  57. for(i=;i<m;i++) wc[i]=;
  58. for(i=;i<n;i++) wc[wd[i]]++;
  59. for(i=;i<m;i++) wc[i]+=wc[i-];
  60. for(i=n-;i>=;i--) sa[--wc[wd[i]]]=y[i];
  61. swap(x,y);
  62. p=; x[sa[]]=;
  63. for(i=;i<n;i++) x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
  64. }
  65. }
  66.  
  67. void getheight(int *r,int *sa,int n)
  68. {
  69. int i,j,k=;
  70. for(i=;i<=n;i++) rank[sa[i]]=i;
  71. for(i=;i<n;height[rank[i++]]=k)
  72. {
  73. if(k) k--;
  74. j=sa[rank[i]-];
  75. while(r[i+k]==r[j+k]) k++;
  76. }
  77. }
  78.  
  79. void init()
  80. {
  81. memset(s,,sizeof(s));
  82. memset(sa,,sizeof(sa));
  83. memset(wa,,sizeof(wa));
  84. memset(wb,,sizeof(wb));
  85. memset(wc,,sizeof(wc));
  86. memset(wd,,sizeof(wd));
  87. memset(height,,sizeof(height));
  88. memset(rank,,sizeof(rank));
  89. }
  90.  
  91. int lcp(int p,int x,int y)
  92. {
  93. int t;
  94. int L=g[p][x];
  95. int R=g[p][y];
  96. if(L>R){t=L; L=R; R=t;}
  97. L++;
  98. int q=Log[R-L+];
  99. return min(f[p][L][q],f[p][R-bin[q]+][q]);
  100. }
  101.  
  102. int query(int x,int y)
  103. {
  104. int q=Log[y-x+];
  105. return min(f[][x][q],f[][y-bin[q]+][q]);
  106. }
  107.  
  108. void solve(int L)
  109. {
  110. for(int i=;i+L<n;i+=L)
  111. if(ch[i]==ch[i+L])
  112. {
  113. int r=lcp(,i,i+L);
  114. // printf("1 %d %d %d\n",i,i+L,r);
  115. int l=lcp(,n-i,n-i-L);
  116. // printf("2 %d %d %d\n",n-i,n-i-L,l);
  117. if((l+r)/L+>mx) {mx=(l+r)/L+; ans=oo;}
  118. if((l+r)/L+==mx)
  119. {
  120. int t=query(i-l,i-l+(l+r)%L);
  121. // printf("%d %d %d\n",i-l,i-l+(l+r)%L,t);
  122. if(t<ans)
  123. {
  124. ans=t;
  125. ansl=save[t];
  126. ansr=ansl+mx*L-;
  127. }
  128. }
  129. }
  130. }
  131.  
  132. int main()
  133. {
  134. //freopen("poj3693.in","r",stdin);
  135. //freopen("poj3693.out","w",stdout);
  136. bin[]=;
  137. for(int i=;i<;i++) bin[i]=bin[i-]<<;
  138. Log[]=-;
  139. for(int i=;i<=;i++) Log[i]=Log[i/]+;
  140. int cas=;
  141. while(scanf("%s",ch))
  142. {
  143. if(ch[]=='#') break;
  144. cas++;
  145. printf("Case %d: ",cas);
  146.  
  147. init();
  148. n=strlen(ch);
  149. for(int i=;i<n;i++) s[i]=ch[i]-'a'+;
  150. s[n]=;
  151. getsa(s,sa,n+,);
  152. getheight(s,sa,n);
  153.  
  154. for(int i=;i<n;i++) f[][i][]=rank[i];
  155.  
  156. int len=Log[n];
  157. for(int i=;i<=n;i++) f[][i][]=height[i];
  158. for(int i=;i<=len;i++)
  159. for(int j=;j+bin[i]-<=n;j++)
  160. f[][j][i]=min(f[][j][i-],f[][j+bin[i-]][i-]);
  161. for(int i=;i<=n;i++) g[][i]=rank[i];
  162. for(int i=;i<=n;i++) save[i]=sa[i];
  163.  
  164. init();
  165. for(int i=;i<n;i++) s[i]=ch[n--i]-'a'+;
  166. s[n]=;
  167. getsa(s,sa,n+,);
  168. getheight(s,sa,n);
  169.  
  170. for(int i=;i<=n;i++) f[][i][]=height[i];
  171. for(int i=;i<=len;i++)
  172. for(int j=;j+bin[i]-<=n;j++)
  173. f[][j][i]=min(f[][j][i-],f[][j+bin[i-]][i-]);
  174. for(int i=;i<=n;i++) g[][i]=rank[i];
  175.  
  176. for(int i=;i<=len;i++)
  177. for(int j=;j+bin[i]-<=n-;j++)
  178. f[][j][i]=min(f[][j][i-],f[][j+bin[i-]][i-]);
  179.  
  180. ansl=ansr=;
  181. mx=; ans=oo;
  182. for(int i=;i<n;i++)
  183. if(ch[i]<ch[ansl]){ans=; ansl=ansr=i;}
  184. for(int i=;i<=n;i++) solve(i);
  185. for(int i=ansl;i<=ansr;i++) printf("%c",ch[i]);
  186. printf("\n");
  187. }
  188. return ;
  189. }

【SPOJ687&POJ3693】Maximum repetition substring(后缀数组)的更多相关文章

  1. POJ3693 Maximum repetition substring —— 后缀数组 重复次数最多的连续重复子串

    题目链接:https://vjudge.net/problem/POJ-3693 Maximum repetition substring Time Limit: 1000MS   Memory Li ...

  2. POJ3693 Maximum repetition substring [后缀数组 ST表]

    Maximum repetition substring Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9458   Acc ...

  3. POJ3693 Maximum repetition substring 后缀数组

    POJ - 3693 Maximum repetition substring 题意 输入一个串,求重复次数最多的连续重复字串,如果有次数相同的,则输出字典序最小的 Sample input ccab ...

  4. poj3693 Maximum repetition substring (后缀数组+rmq)

    Description The repetition number of a string is defined as the maximum number R such that the strin ...

  5. Maximum repetition substring 后缀数组

    Maximum repetition substring Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7578   Acc ...

  6. POJ 3693 Maximum repetition substring ——后缀数组

    重复次数最多的字串,我们可以枚举循环节的长度. 然后正反两次LCP,然后发现如果长度%L有剩余的情况时,答案是在一个区间内的. 所以需要找到区间内最小的rk值. 两个后缀数组,四个ST表,$\Thet ...

  7. 【Poj-3693】Maximum repetition substring 后缀数组 连续重复子串

    POJ - 3693 题意 SPOJ - REPEATS的进阶版,在这题的基础上输出字典序最小的重复字串. 思路 跟上题一样,先求出最长的重复次数,在求的过程中顺便纪录最多次数可能的长度. 因为sa数 ...

  8. poj 3693 Maximum repetition substring (后缀数组)

    其实是论文题.. 题意:求一个字符串中,能由单位串repeat得到的子串中,单位串重复次数最多的子串.若有多个重复次数相同的,输出字典序最小的那个. 解题思路:其实跟论文差不多,我看了很久没看懂,后来 ...

  9. POJ 3693 Maximum repetition substring (后缀数组+RMQ)

    题意:给定一个字符串,求其中一个由循环子串构成且循环次数最多的一个子串,有多个就输出最小字典序的. 析:枚举循环串的长度ll,然后如果它出现了两次,那么它一定会覆盖s[0],s[ll],s[ll*2] ...

  10. poj3693 Maximum repetition substring

    题意 给出一个长度为\(n(n\leqslant 100000)\)的串,求一个字典序最小的子串使得它是某个字符串重复\(k\)次得到的,且\(k\)最大 题解 后缀数组论文上的题,跟上一篇uva那个 ...

随机推荐

  1. GNU make(2)

    GNU make(2) 参考: GNU Make学习总结(二) 变量 变量由一个前导符号$加上字符或者是括号字符组成, 名称区分大小写. 命名: 习惯上用全部大写字符表示常量, 小写字符表示变量, 单 ...

  2. fluent_python1

    Magic Method python中有些跟对象本身有关的方法, 以两个下划线开始,两个下划线结束, 一般称为魔法方法(magic method). 比如 obj[key] 的背后就是 __geti ...

  3. Gym - 101291C (很有意思的最短路)

    题意: 给出一张地图和机器人还有出口的位置,地图上面有障碍.然后给出UDLR上下左右四种指令,遇到障碍物或者越界的指令会忽略,剩下的继续执行. 只要到达出口就算找到出口,然后给你一串指令,让你修改指令 ...

  4. (三)VMware harbor使用http访问

    参考:https://www.cnblogs.com/biglittleant/p/7283738.html harbor使用http访问 如果使用http启动harbor需要在docker中配置-- ...

  5. CPP-基础:wchar_t

    目 录 1简介 2例如 3将char转换成wchar_t 1.简介 wchar_t是C/C++的字符数据类型,是一种扩展的字符存储方式,wchar_t类型主要用在国际化程序的实现中,但它不等同于uni ...

  6. 【转】Python 访问 HDFS

    1.前言 hdfs , Hadoop Distributed File System.Hadoop的分布式文件系统,安全行和扩展性没得说. 访问HDFS的方式有以下几种: 命令行方式:FS Shell ...

  7. WebStorm换主题(护眼)

    一.下载喜欢颜色的主题 http://www.phpstorm-themes.com/ 我用的豆沙绿护眼 <scheme name="Solarized Light My" ...

  8. 数据库事务ACID和事务的隔离级别

    借鉴:https://blog.csdn.net/zh521zh/article/details/69400053和https://blog.csdn.net/May_3/article/detail ...

  9. (2)zabbix硬件需求

    1. 硬件需求 无非就是cpu.内存.硬盘之类的1.1 CPU由你的zabbix数据库使用情况来做决定,如果你监控的项目越多,那你的cpu要越好.具体多好,下面有个表格 1.2 内存与硬盘最基本的需求 ...

  10. linux各种终端类型的区别和概念

    1 pty(虚拟终端或伪终端): 当我们远程telnet到主机或使用xterm时不也需要一个终端交互么?是的,这就是虚拟终端pty(pseudo-tty). 2 tty(终端设备的统称):tty一词源 ...