您的位置:首页 > 其它

【后缀数组】SPOJ REPEATS

2015-02-12 14:11 363 查看
先存代码,题解之后再传。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int MAXN = 50000,MAXM = 128;
int n,len;
const int maxlog = 20;
char a[MAXN +10];
int rank[MAXN +10],sa[MAXN +10],end[MAXN +10],nsa[MAXN +10],trank[MAXN +10];
int h[MAXN +10],f[MAXN+10][30];
bool cmpr(int i,int j)
{
if(trank[i] == trank[j])
{
if(i+len >= n)
return 1;
else if(j + len >= n)
return 0;
return trank[i+len] < trank[j+len];
}
return trank[i] < trank[j];
}
void calc_sa()
{
int i;
for(i = 0;i < MAXM;i++)
end[i] = 0;
for(i = 0;i < n;i++)
end[a[i]]++;
for(i = 1;i < MAXM;i++)
end[i] += end[i-1];
for(i = 0;i < n;i++)
rank[i] = a[i] > 0?end[a[i]-1]:0;
for(i = 0;i < n;i++)
sa[--end[a[i]]] = i;
for(int k = 1;k < n;k <<= 1)
{
int ok = 1;
len = k;
for(i = 0;i < n;i++)
end[rank[sa[i]]] = i;
for(i = n - 1;i >= 0;i--)
{
if(sa[i] >= len)
nsa[end[rank[sa[i]-len]]--] = sa[i]-len;
}
for(i = n - len;i < n;i++)
{
nsa[end[rank[i]]--] = i;
}
for(i = 0;i < n;i++)
{
trank[i] = rank[i];
sa[i] = nsa[i];
}
rank[sa[0]] = 0;
for(int i = 1;i < n;i++)
{
if(!cmpr(sa[i-1],sa[i]) && !cmpr(sa[i],sa[i-1]))
{
rank[sa[i]] = rank[sa[i-1]];
ok = 0;
}
else
{
rank[sa[i]] = i;
}
}
if(ok) break;
}
/*
for (int i=0;i<n;i++)
printf("rank[%d]=%d\n",i,rank[i]);
for(int i=0;i<n;i++)
printf("%d=%d\n",i,sa[i]);
*/
}
void get_height()
{
int i,j,k = 0;
for(int i = 0; i < n; i++) rank[sa[i]] = i;
for(i = 0;i < n;i++)
{
if(k) k--;
if(rank[i])
{
j = sa[rank[i] - 1];
while(a[i+k] == a[j+k]) k++;
h[rank[i]] = k;
}
}
}
void init_RMQ()
{
int i,j;
memset(f,0,sizeof(f));
for(i = 0;i < n;i++) f[i][0] = h[i];
for(j = 1;j < 20;j++)
for(i = 0;i + (1 << j) <= n;i++)
f[i][j] = min(f[i][j-1], f[i+(1<<(j-1))][j-1]);
}
int lcp(int a,int b)
{
int x = rank[a],y = rank[b];
if(x > y)
swap(x,y);
x++;
int k = (int)(log(y-x+1.0) / log(2.0));//log(y - x + 1)
return min(f[x][k], f[y-(1 << k)+1][k]);
}
int main()
{
int T,i,l,st,ans;
for(scanf("%d",&T);T;T--)
{
scanf("%d",&n);
for(i = 0;i < n;i++)
scanf(" %c",&a[i]);
a
= 0;
ans = 0;
calc_sa();
get_height();
init_RMQ();
for(l = 1;l < n;l++)
for(st = 0;st + l < n;st += l)
{
int k = lcp(st, st+l);
if(k < l) continue;
int times = k / l + 1;
int t = st - (l - k % l);
if(t >= 0 && lcp(t, t + l) >= l) times++;
ans = max(ans,times);
}
printf("%d\n",ans);
}
}
/*
1
17
b
a
b
b
a
b
a
a
b
a
a
b
a
a
b
a
b
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: