POJ 3693 Maximum repetition substring(RMQ+后缀数组)
来源:互联网 发布:深圳知复科技有限公司 编辑:程序博客网 时间:2024/04/30 20:52
http://blog.csdn.net/acm_cxlove/article/details/7941205
lcp(i,j);
字符串suffix(i) 和 suffix(j)的最长公共前缀
然后就是比较神奇的简化。。
#include <stdio.h> #include <math.h> #include <string.h> #include <algorithm> #include<iostream>using namespace std; const int N = 100010; int r[N], tx[N], ty[N], rs[N], ranks[N], sa[N], height[N], rmq[N][20]; //rs基数排序 char s[N]; bool cmp(int *r, int a, int b, int len) { return (r[a] == r[b]) && (r[a + len] == r[b + len]); } void suffix(int n, int m) //n为长度,最大值小于m { int i, j, p, *x = tx, *y = ty, *t; for(i = 0; i < m; ++i) rs[i] = 0; for(i = 0; i < n; ++i) { x[i] = r[i]; ++rs[x[i]]; } for(i = 1; i < m; ++i) rs[i] += rs[i - 1]; for(i = n - 1; i >= 0; --i) sa[--rs[x[i]]] = i; for(j = p = 1; p < n; j <<= 1, m = p) { for(p = 0, i = n - j; i < n; ++i) y[p++] = i; for(i = 0; i < n; ++i) { if(sa[i] >= j) y[p++] = sa[i] - j; } for(i = 0; i < m; ++i) rs[i] = 0; for(i = 0; i < n; ++i) ++rs[x[y[i]]]; for(i = 1; i < m; ++i) rs[i] += rs[i - 1]; for(i = n - 1; i >= 0; --i) sa[--rs[x[y[i]]]] = y[i]; t = x, x = y, y = t; for(i = 1, p = 1, x[sa[0]] = 0; i < n; ++i) { if(cmp(y, sa[i - 1], sa[i], j)) x[sa[i]] = p - 1; else x[sa[i]] = p++; } } /**for(i = 0; i < n; ++i) printf("%s\n", s + sa[i]);*/ } void calheight(int n) { int i, j, k = 0; for(i = 1; i <= n; ++i) ranks[sa[i]] = i; for(i = 0; i < n; ++i) { if(k) --k; j = sa[ranks[i] - 1]; while(r[i + k] == r[j + k]) ++k; height[ranks[i]] = k; } } void initrmq(int n) { int i, k; for(i = 2; i <= n; ++i) rmq[i][0] = height[i]; for(k = 1; (1 << k) <= n; ++k) { for(i = 2; i + (1 << k) - 1 <= n; ++i) { rmq[i][k] = min(rmq[i][k - 1], rmq[i + (1 << (k - 1))][k - 1]); } } } int lcp(int a, int b) { a = ranks[a], b = ranks[b]; if(a > b) swap(a, b); ++a; int k = (int) (log((b - a + 1) * 1.0) / log(2.0)); return min(rmq[a][k], rmq[b - (1 << k) + 1][k]); } int a[N];int main(){int ans=0;while(cin>>s,s[0]!='#'){ans++;int i,j,k,l;int n=strlen(s);for(i=0;i<n;i++)r[i]=s[i];r[n]=0;suffix(n+1,180);calheight(n);initrmq(n);int mx=0,cnt;for(l=1;l<n;l++){for(i=0;i+l<n;i+=l){int t=lcp(i,i+l);int m=t/l+1;//现在的个数int h=l-(t%l);//需要向前移if(i-h>=0 && t%l)if(lcp(i-h,i+l-h)>=t)m++;if(m>mx){mx=m;cnt=0;a[cnt++]=l;}else if(m==mx)a[cnt++]=l;}}int len=-1,st;for(i=1;i<=n&&len==-1;i++){for(j=0;j<cnt;j++){if(lcp(sa[i],sa[i]+a[j])>=(mx-1)*a[j]){len=a[j];st=sa[i];break;}}}int he=len*mx;printf("Case %d: ",ans);for(i=st;i<st+he;i++) printf("%c",r[i]);printf("\n");}}
0 0
- POJ 3693 Maximum repetition substring(RMQ+后缀数组)
- poj 3693 Maximum repetition substring (后缀数组+RMQ)
- poj 3693 Maximum repetition substring 后缀数组+RMQ
- POJ 3693 Maximum repetition substring 后缀数组 暴力 rmq
- POJ 3693 Maximum repetition substring 后缀数组 + RMQ预处理
- POJ 3693 Maximum repetition substring后缀数组加上RMQ
- POJ 3693 Maximum repetition substring RMQ+后缀数组
- POJ 3693 Maximum Repetition Substring <后缀数组 + RMQ>
- POJ 3693 Maximum repetition substring(08合肥 RMQ+后缀数组)
- poj 3693 Maximum repetition substring(08合肥 RMQ+后缀数组)
- poj 3693 Maximum repetition substring //后缀数组
- poj 3693 Maximum repetition substring (后缀数组)
- poj 3693 Maximum repetition substring(后缀数组)
- poj 3693 Maximum repetition substring(后缀数组)
- 【后缀数组】【poj 3693】Maximum repetition substring
- POJ 3693 Maximum Repetition Substring 后缀数组
- poj3693 Maximum repetition substring 后缀数组+RMQ
- POJ3693:Maximum repetition substring(后缀数组+RMQ)
- Sql server 数据查询与操作(一)
- IOS开发之格式化日期时间
- TCP.普通socket(阻塞/非阻塞)模型
- linux 下查看机器cpu是几核的
- Android 通过monkey获取包名和类名
- POJ 3693 Maximum repetition substring(RMQ+后缀数组)
- android相对布局
- 解决phpcms v9视频模块的“该视频不存在”
- java多态中的引用与C语言中的指针比较
- hadoop版本比较
- 阿里巴巴4个不要人理由:不想长年累月加班
- 最近的迷茫
- 游戏系统
- /usr/include/stdlib.h:140:8: error: 'size_t' does not name a type