首页 > 代码库 > [POJ2406]Power Strings
[POJ2406]Power Strings
传送门
给定一个字符串 L,已知这个字符串是由某个字符串 S 重复 R 次而得到的,求 R 的最大值。
1.后缀数组
做法比较简单,穷举字符串 S 的长度 k,然后判断是否满足。判断的时候,
先看字符串 L 的长度能否被 k 整除,再看 suffix(1)和 suffix(k+1)的最长公共
前缀是否等于 n-k。在询问最长公共前缀的时候,suffix(1)是固定的,所以 RMQ 问题没有必要做所有的预处理,只需求出 height 数组中的每一个数到
height[rank[1]]之间的最小值即可。
因为用的是倍增求后缀数组,TLE,然而不会 DC3,正确性。。。。不知道(但至少思路是对的,你敢质疑罗大牛?)
——代码
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #define N 1000001 5 #define min(x, y) ((x) < (y) ? (x) : (y)) 6 7 int len, n, m, ans; 8 int buc[N], x[N], y[N], sa[N], rank[N], height[N], d[N]; 9 char s[N];10 11 inline void build_sa()12 {13 int i, k, p;14 for(i = 0; i < m; i++) buc[i] = 0;15 for(i = 0; i < len; i++) buc[x[i] = s[i]]++;16 for(i = 1; i < m; i++) buc[i] += buc[i - 1];17 for(i = len - 1; i >= 0; i--) sa[--buc[x[i]]] = i;18 for(k = 1; k <= len; k <<= 1)19 {20 p = 0;21 for(i = len - 1; i >= len - k; i--) y[p++] = i;22 for(i = 0; i < len; i++) if(sa[i] >= k) y[p++] = sa[i] - k;23 for(i = 0; i < m; i++) buc[i] = 0;24 for(i = 0; i < len; i++) buc[x[y[i]]]++;25 for(i = 1; i < m; i++) buc[i] += buc[i - 1];26 for(i = len - 1; i >= 0; i--) sa[--buc[x[y[i]]]] = y[i];27 std::swap(x, y);28 p = 1, x[sa[0]] = 0;29 for(i = 1; i < len; i++)30 x[sa[i]] = y[sa[i - 1]] == y[sa[i]] && y[sa[i - 1] + k] == y[sa[i] + k] ? p - 1 : p++;31 if(p >= len) break;32 m = p;33 }34 }35 36 inline void build_height()37 {38 int i, j, k = 0;39 for(i = 0; i < len; i++) rank[sa[i]] = i;40 for(i = 0; i < len; i++)41 {42 if(!rank[i]) continue;43 if(k) k--;44 j = sa[rank[i] - 1];45 while(s[i + k] == s[j + k] && i + k < len && j + k < len) k++;46 height[rank[i]] = k;47 }48 }49 50 inline void RMQ_init()51 {52 int i, k;53 k = rank[0], d[k] = len;54 for(i = k - 1; i >= 0; i--) d[i] = min(d[i + 1], height[i + 1]);55 for(i = k + 1; i < len; i++) d[i] = min(d[i - 1], height[i]);56 }57 58 inline int RMQ(int k)59 {60 return d[rank[k]];61 }62 63 inline int solve()64 {65 int i;66 for(i = 1; i <= len / 2; i++)67 if(!(len % i))68 if(RMQ(i) == (len - i))69 return len / i;70 return 1;71 }72 73 int main()74 {75 while(scanf("%s", s) && s[0] ^ ‘.‘)76 {77 m = 256;78 len = strlen(s);79 build_sa();80 build_height();81 RMQ_init();82 printf("%d\n", solve());83 }84 return 0;85 }
可见后缀数组并不是正解。
2.kmp(没细致研究过,以后补)
[POJ2406]Power Strings
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。