关闭

poj3693 后缀数组+RMQ

44人阅读 评论(0) 收藏 举报
分类:

感觉思路还是非常神奇的。另外注意一下strlen好像是个on的函数。。。日狗。。tle了一个晚上。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
#define maxn 100005
#define forup(i,a,b)  for(int i=(a);i<=(b);i++)
#define fordown(i,b,a)  for(int i=b;i>=a;i--)
#define Rank rk 
int n;
int a[maxn];
int sum[maxn],rk[maxn],r1[maxn],r2[maxn],sa1[maxn],sa2[maxn],height[maxn];
void solve()
{  memset(sum,0,sizeof(sum)); 
 forup(i,1,n)  sum[a[i]]++;
    forup(i,1,130)  sum[i]+=sum[i-1];
    forup(i,1,n)   rk[i]=sum[a[i]-1]+1;
    int k=1;
while(k<n)
{   forup(i,1,n)  
  {r1[i]=rk[i];
     if(i+k<=n)  r2[i]=rk[i+k];
     else r2[i]=0; 
  }
  
  memset(sum,0,sizeof(sum));
forup(i,1,n)     sum[r2[i]]++;
forup(i,1,n)     sum[i]+=sum[i-1];
fordown(i,n,1)    sa2[sum[r2[i]]]=i,sum[r2[i]]--;


  memset(sum,0,sizeof(sum));
  forup(i,1,n)  sum[r1[i]]++;
  forup(i,1,n)   sum[i]+=sum[i-1];
  fordown(i,n,1)   sa1[sum[r1[sa2[i]]]]=sa2[i],sum[r1[sa2[i]]]--;
  
  
  rk[sa1[1]]=1;
  forup(i,2,n)
  {rk[sa1[i]]=rk[sa1[i-1]];
   if(!(r1[sa1[i]]==r1[sa1[i-1]]&&r2[sa1[i]]==r2[sa1[i-1]]))  rk[sa1[i]]++;
  }
 if(rk[sa1[n]]>=n)  break;
k=k<<1;
}

     height[1]=0;int l=0;
     forup(i,1,n)//其实感觉最后直接用rank的顺序来搞亦可以,但是好像并没有人这么写那就算了。。。
     { if(rk[i]>1)
        {   int k=sa1[rk[i]-1];
           while(i+l<=n&&k+l<=n&&a[i+l]==a[k+l])   l++;
           height[rk[i]]=l;
           if(l>0)  l--;
       }
     }
}

int dp[maxn][20];
void  getrmq()
{//memset(dp,0,sizeof(dp)); 
    int m=floor(log(n+0.0)/log(2.0));  
    for(int i=1;i<=n;i++) dp[i-1][0]=height[i];  
    for(int i=1;i<=m;i++){  
        for(int j=n;j;j--){  
            dp[j][i]=dp[j][i-1];  
            if(j+(1<<(i-1))<=n)  
                dp[j][i]=min(dp[j][i],dp[j+(1<<(i-1))][i-1]);  
        }  
    }  
}  

int Rmq_Query(int l,int r){  
    int a=Rank[l],b=Rank[r];  
    if(a>b) swap(a,b);  
     
    int m=floor(log(b-a)/log(2.0));  
    return min(dp[a][m],dp[b-(1<<m)][m]);  
}  

char str[maxn];
int main()
{ //freopen("1.in","r",stdin);  

 int  cas=0;
  while(scanf("%s",str)!=EOF&&str[0]!='#')
  {  
  n=strlen(str);
  
     forup(i,0,n-1)
     { a[i+1]=str[i]; }
   solve();
  getrmq();
 int cnt=0,mmax=0,a[maxn];  
        for(int l=1;l<n;l++){  
            for(int i=1;i+l<=n;i+=l){  
                int r=Rmq_Query(i,i+l);  
                int step=r/l+1;  
                int k=i-(l-r%l);  
                if(k>=0&&r%l)  
                    if(Rmq_Query(k,k+l)>=r)   
                        step++;  
                if(step>mmax){  
                    mmax=step;  
                    cnt=0;  
                    a[cnt++]=l;  
                }  
                else if(step==mmax)  
                    a[cnt++]=l;  
            }  
        }  
        int len=-1,st;  
        for(int i=1;i<=n&&len==-1;i++){  
            for(int j=0;j<cnt;j++){  
                int l=a[j];  
                if(Rmq_Query(sa1[i],sa1[i]+l)>=(mmax-1)*l){  
                    len=l;  
                    st=sa1[i];  
                    break;  
                }  
            }  
        }  
        printf("Case %d: ",++cas);  
        for(int i=st-1,j=0;j<len*mmax;j++,i++) printf("%c",str[i]);  
        printf("\n");  
    }  
	return 0;
 } 


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:10677次
    • 积分:755
    • 等级:
    • 排名:千里之外
    • 原创:57篇
    • 转载:58篇
    • 译文:0篇
    • 评论:16条
    文章分类
    最新评论