| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
nlog(n)的后缀数组怎么才能过#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <algorithm>
using namespace std;
#define M 51000
#define N 100000 //排序数组的大小
int K;
int SA[N][20]; //后缀数组
int RANK[N][20]; //名次数组
int h[N]; //h[i]=height[RANK[i]]
int height[N]; //height[i]=LCP(i-1,i)
int RMQ[N][20]; //对height数组进行RMQ运算
int B[N];
int C[M]; //计数数组
int LEN;
bool mark[N];
char S[N]; //等处理字符串
char ori[N];
char buf[N];
int ins[N],ni;
int INS[N],NI;
//计算后缀数组SA与名次数组RANK
void SUFFIX_ARRAY_INIT(char *s)
{
int i,j,OFFSET,p;
for(K=0;;K++) if ((1<<K)>=LEN) break;
//先对长为1的前缀进行排序,即对SA[][0]进行排序
memset(C,0,sizeof(C));
for(i=0;i<LEN;i++) C[s[i]]++;
for(i=1;i<200;i++) C[i]+=C[i-1];
for(i=LEN-1;i>=0;i--){
C[s[i]]--;
B[C[s[i]]]=i;
}
for(i=0;i<LEN;i++){
SA[i][0]=B[i];
if (i&&S[B[i]]==S[B[i-1]]) RANK[B[i]][0]=RANK[B[i-1]][0];
else RANK[B[i]][0]=i;
}
OFFSET=1;
for(j=1;j<=K;j++){
printf("%d\n",clock());
memset(C,0,sizeof(C));
for(i=0;i<LEN;i++) C[RANK[i+OFFSET][j-1]]++;
for(i=1;i<LEN;i++) C[i]+=C[i-1];
for(i=LEN-1;i>=0;i--){
C[RANK[i+OFFSET][j-1]]--;
B[C[RANK[i+OFFSET][j-1]]]=i;
}
memset(C,0,sizeof(C));
for(i=0;i<LEN;i++) C[RANK[B[i]][j-1]]++;
for(i=1;i<LEN;i++) C[i]+=C[i-1];
for(i=LEN-1;i>=0;i--){
C[RANK[B[i]][j-1]]--;
SA[C[RANK[B[i]][j-1]]][j]=B[i];
}
for(i=0;i<LEN;i++){
if (i&&RANK[SA[i][j]+OFFSET][j-1]==RANK[SA[i-1][j]+OFFSET][j-1]
&&RANK[SA[i][j]][j-1]==RANK[SA[i-1][j]][j-1])
RANK[SA[i][j]][j]=RANK[SA[i-1][j]][j];
else RANK[SA[i][j]][j]=i;
}
OFFSET<<=1;
}
height[0]=0;
for(i=0;i<LEN;i++){
if (RANK[i][K]==0) h[i]=0;
else{
if (i==0||h[i-1]<=1){
for(p=0;;p++) if (s[i+p]!=s[SA[RANK[i][K]-1][K]+p]) break;
h[i]=p;
}
else{
for(p=h[i-1]-1;;p++) if (s[i+p]!=s[SA[RANK[i][K]-1][K]+p]) break;
h[i]=p;
}
}
}
for(i=1;i<LEN;i++) height[i]=h[SA[i][K]];
}
void RMQ_INIT(int *height,int n)
{
int K=0,i,j;
while(((1<<(K+1)))<=n) K++;
for(i=0;i<n;i++) RMQ[i][0]=height[i];
for(j=1;j<=K;j++){
for(i=0;i<=n-(1<<j);i++)
RMQ[i][j]=
RMQ[i][j-1]<RMQ[i+(1<<(j-1))][j-1]?RMQ[i][j-1]:RMQ[i+(1<<(j-1))][j-1];
}
}
int lcp(int i,int j)
{
int k=0;
if (i==j) return LEN-1-SA[i][K];
if (i>j) swap(i,j);
i++;
while((1<<(k+1))<=(j-i+1)) k++;
return RMQ[i][k]<RMQ[j-(1<<k)+1][k]?RMQ[i][k]:RMQ[j-(1<<k)+1][k];
}
int query(int i,int j,int ii,int jj)
{
int k,na,nb,len,ret,m,ti=0,tj;
len=strlen(S);
if (i==j){
for(k=NI-1;k>=0;k--) if (INS[k]>i) ti++;else break;
return LEN-1-i+ti;
}
na=nb=LEN-1;
for(k=ii;k<NI;k++) if (INS[k]>i){
na=INS[k];
break;
}
ti=k;
for(k=jj;k<NI;k++) if (INS[k]>j){
nb=INS[k];
break;
}
tj=k;
ret=lcp(RANK[i][K],RANK[j][K]);
m=na-i<nb-j?na-i:nb-j;
if (ret<m) return ret;
ret=m;
i=i+m+ti;
j=j+m+tj;
for(;i<len&&j<len&&S[i]==S[j];i++,j++){
if (!mark[i]&&!mark[j]) return ret+query(i-ti,j-tj,ti,tj);
if (mark[i]) ti++;
if (mark[j]) tj++;
ret++;
}
return ret;
}
int main()
{
int i,j,k,p,t,len;
char c[2];
freopen("input.dat","r",stdin);
while(scanf("%s",S)!=EOF){
strcpy(ori,S);
LEN=strlen(S)+1;
memset(RANK,0,sizeof(RANK));
memset(mark,0,sizeof(mark));
SUFFIX_ARRAY_INIT(S);
//printf("%d\n",clock());
RMQ_INIT(height,LEN);
//printf("%d\n",clock());
//return 0;
NI=ni=0;
scanf("%d",&k);
while(k--){
scanf("%s",c);
switch(c[0]){
case 'I':
scanf("%s%d",c,&p);
if (p>strlen(S)){
S[strlen(S)+1]=0;
S[strlen(S)]=c[0];
ins[ni]=strlen(S)-1;
mark[ins[ni]]=1;
ni++;
INS[NI++]=LEN-1;
}
else{
strcpy(buf,S+p-1);
S[p-1]=c[0];
strcpy(S+p,buf);
len=strlen(S);
for(i=ni-1;i>=0;i--)
if (ins[i]>=p-1){
ins[i+1]=ins[i]+1;
mark[ins[i]]=0;
mark[ins[i+1]]=1;
}else break;
ins[i+1]=p-1;
mark[p-1]=1;
ni++;
t=0;
for(i=0;i<ni;i++) if (ins[i]<p-1) t++;
t=p-1-t;
for(i=NI-1;i>=0;i--)
if (INS[i]>t)INS[i+1]=INS[i];
else break;
INS[i+1]=t;
NI++;
}
break;
case 'Q':
scanf("%d%d",&i,&j);
i--;j--;
printf("%d\n",query(i,j,0,0));
break;
}
}
}
return 0;
}
Followed by:
Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator