LA 4513

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2514

此题需要求在一个字符串中出现至少k次的最长子串, 如果有多个, 取rightmost的那个 , 还是用后缀数组 , 二分然后分段处理 , 不过也可以用hash解决 , 这里先给出后缀数组的代码 。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<string>
  5 #include<algorithm>
  6
  7 const int N = 44444 ;
  8
  9 using namespace std ;
 10
 11 char str[N] ;
 12 int sa[N] , n , rank[N] , height[N] , t1[N] , t2[N] , c[N] , k;
 13
 14 void build_sa( int m )
 15 {
 16      int *x = t1 , *y = t2 ;
 17
 18      for( int i=0;i<m;i++ ) c[i] = 0 ;
 19
 20      for( int i=0;i<n;i++ ) c[ x[i]=str[i] ] ++ ;
 21
 22      for( int i=1;i<m;i++ ) c[i] += c[i-1] ;
 23
 24      for( int i=n-1;i>=0;i-- ) sa[ --c[ x[i] ] ] = i ;
 25
 26      for( int k=1;k<=n;k<<=1 ){
 27               int p = 0 ;
 28
 29               for( int i=n-k;i<n;i++ ) y[p++] = i ;
 30
 31               for( int i=0;i<n;i++ ) if( sa[i]>=k ) y[p++] = sa[i] - k ;
 32
 33               for( int i=0;i<m;i++ ) c[i] = 0 ;
 34
 35               for( int i=0;i<n;i++ ) c[ x[y[i]] ] ++ ;
 36
 37               for( int i=1;i<m;i++ ) c[i] += c[i-1] ;
 38
 39               for( int i=n-1;i>=0;i-- ) sa[ --c[ x[y[i]] ] ] = y[i] ;
 40
 41               p = 1 ; swap( x , y ) ;
 42
 43               x[ sa[0] ] = 0 ;
 44
 45               for( int i=1;i<n;i++ )
 46                        x[ sa[i] ] = y[sa[i-1]] == y[sa[i]] && y[sa[i-1]+k]==y[sa[i]+k] ? p-1 : p++ ;
 47
 48               if( p>=n ) break ;
 49
 50               m = p ;
 51      }
 52 }
 53
 54 void get_height()
 55 {
 56      for( int i=0;i<n;i++ ) rank[ sa[i] ] = i ;
 57
 58      int k = 0 ;
 59
 60      for( int i=0;i<n;i++ ){
 61               if( k ) k-- ;
 62
 63               int j = sa[ rank[i]-1 ] ;
 64
 65               while( str[i+k]==str[j+k] ) k ++ ;
 66
 67               height[ rank[i] ] = k ;
 68      }
 69
 70      height[n] = 0 ;
 71
 72     /* for( int i=1;i<n;i++ ){
 73               for( int j=sa[i];j<n-1;j++ )
 74                        cout<<str[j]<<" ";
 75               cout<<endl;
 76      }*/
 77 }
 78
 79 bool is_ok( int mid )
 80 {
 81      int pre = 1 ;
 82
 83      for( int i=2;i<=n;i++ ){
 84               if( height[i]<mid ){
 85                                 if( i-pre>=k ) return true ;
 86                                 pre = i ;
 87               }
 88      }
 89
 90      return false ;
 91 }
 92
 93 void print( int mid )
 94 {
 95      int pre = 1 , Max = 0 ;
 96
 97      for( int i=2;i<=n;i++ ){
 98               if( height[i]<mid ){
 99                                 if( i-pre>=k && height[i-1]>=mid ){
100                                     for( int j=pre;j<i;j++ )
101                                              Max = max( Max , sa[j] ) ;
102                                 }
103                                 pre = i ;
104               }
105      }
106
107      printf("%d %d\n" , mid , Max);
108 }
109
110 int main()
111 {
112     while( scanf("%d" , &k)!=EOF && k )
113     {
114            scanf("%s" , str) ;
115
116            n = strlen(str) ;
117
118            str[n] = ‘a‘ - 1 ;
119
120            n++ ;
121
122            build_sa(127) ;  get_height() ;
123
124            int l = 0 , r = n-1 ;
125
126            while( l<r ){
127                       if( l==r-1 ) break ;
128
129                       int mid = ( l+r ) >> 1 ;
130
131                       if( is_ok(mid)==true )
132                                            l = mid ;
133                       else                 r = mid - 1 ;
134            }
135
136            if( is_ok(r)==true ) print(r) ;
137            else if( l==0 ) printf("none\n");
138            else print(l) ;
139     }
140 }
时间: 2024-12-14 18:41:04

LA 4513的相关文章

LA 4513 Stammering Aliens 字符串hash

字符串hash模板, 本题是求,给定字符串s中至少出现m次的最长字符串长度,及此时起始位置的最大值 LA 4513  Stammering Aliens 白书p225 //#pragma warning (disable: 4786) //#pragma comment (linker, "/STACK:16777216") //HEAD #include <cstdio> #include <ctime> #include <cstdlib> #i

LA 4513 hash表示字符串后缀

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=&problem=2514&mosmsg=Submission+received+with+ID+1623942 Dr. Ellie Arroway has established contact with an extraterrestrial civiliz

字符串hash LA 4513 Stammering Aliens

题目传送门 题意:训练之南P225 分析:二分寻找长度,用hash值来比较长度为L的字串是否相等. #include <bits/stdc++.h> using namespace std; typedef unsigned long long ull; const int N = 4e4 + 5; const int x = 123; ull H[N], _hash[N], xp[N]; int rk[N]; char str[N]; int m; void get_hash(char *s

hdu 5745 la vie en rose

这道题的官方题解是dp,但是可以暴力出来.改天再研究怎么dp. 暴力的时候,如果计算sum的时候,调用strlen函数会超时,可见这个函数并不是十分的好.以后能不用尽量不用. La Vie en rose Time Limit: 14000/7000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 861    Accepted Submission(s): 461 Problem

让MAC OS也能使用LL LA L等LS的别名

linux下默认ll是ls -l的别名.OS X下默认不支持.习惯了linux下使用ll,我们同样也可以将习惯搬到os x下的shell中. 再当前用户家目录下新建.bash_profile文件.根据你的习惯,添加下面格式内容即可. 1 2 3 alias ll='ls -l' alias la='ls -a' alias l='ls -la' 然后执行:source .bash_profile你还可以添加你喜欢的其他别名.

LA 3942 Remember the Word (Trie)

Remember the Word 题目:链接 题意:给出一个有S个不同单词组成的字典和一个长字符串.把这个字符串分解成若干个单词的连接(单词可以重复使用),有多少种方法? 思路:令d[i]表示从字符i开始的字符串(后缀s[i..L])的分解数,这d[i] = sum{d(i+len(x)) | 单词x是其前缀}.然后将所有单词建成一个Trie树,就可以将搜索单词的复杂度降低. 代码: #include<map> #include<set> #include<queue>

LA 2678 Subsequence

有一个正整数序列,求最短的子序列使得其和大于等于S,并输出最短的长度. 用数组b[i]存放序列的前i项和,所以b[i]是递增的. 遍历终点j,然后在区间[0, j)里二分查找满足b[j]-b[i]≥S的最大的i,时间复杂度为O(nlongn). 这里二分查找用到库函数lower_bound() 1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #inclu

LA 4127 - The Sky is the Limit (离散化 扫描线 几何模板)

题目链接 非原创 原创地址:http://blog.csdn.net/jingqi814/article/details/26117241 题意:输入n座山的信息(山的横坐标,高度,山底宽度),计算他们的轮廓线, 即露出来的表面边长,有些山是重叠的不计.空白地带不计,每座山都是等腰三角形. 分析:大白书P414页. 求小山的总长度,用一些虚线将其离散化,分成一段一段的,特征点:山脚,山顶,交点.这样就能保 证相邻两个扫描点之间再无交点.然后一最上面的点就是分割点,维护上一个点lastp即可. 1

LA 2031

Mr. White, a fat man, now is crazy about a game named ``Dance, Dance, Revolution". But his dance skill is so poor that he could not dance a dance, even if he dances arduously every time. Does ``DDR" just mean him a perfect method to squander his