poj3693 后缀数组+RMQ

原创 2016年08月28日 19:16:30

感觉思路还是非常神奇的。另外注意一下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;
 } 


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

POJ 3693 Maximum repetition substring(RMQ+后缀数组)

http://blog.csdn.net/acm_cxlove/article/details/7941205 lcp(i,j); 字符串suffix(i) 和 suffix(j)的最长公共前...

POJ 3693 Maximum repetition substring(08合肥 RMQ+后缀数组)

转载请注明出处,谢谢http://blog.csdn.net/acm_cxlove/article/details/7854526       by---cxlove 题目:给出一个串,求重复次...

Poj 3693 & Hdu 2459 Maximum repetition substring (08合肥Online 后缀数组+RMQ 重复次数最多的连续重复子串)

题意:给定一个字符串,求重复次数最多的连续重复子串,当有duo。

POJ 3693 Maximum repetition substring (后缀数组+RMQ 求重复最多的连续子串)

/* * POJ 3693 Maximum repetition substring * 先穷举长度L,然后求长度为L的子串最多能连续出现多少次 * 既然长度为L的串重复出现,那么str[0],...

POJ 3693 后缀数组+RMQ

点击打开链接 题意:问连续重复部分最多的串是什么,不能重叠,且我们要字典序最小的串如xbcabcab,有bcabca重复次数为2,cabcab重复次数也为2,那么要前边那个 思路:以前写过一个类似...

POJ 3693 Maximum repetition substring 后缀数组 + RMQ预处理

题目大意: 定义一个字符串的repetition number表示这个字符串某个重复出现的子串的出现次数, 每次出现不重合比如abababab是ab重复4次其repetition number是4, ...

poj 3693 Maximum repetition substring 后缀数组+RMQ

题目链接: 题意:

HDU 2459 PKU 3693 Maximum repetition substring 后缀数组 RMQ

题目地址:HDU 2459 PKU 3696题意:给一个长度不超过1e51e5的字符串,找出其中一个子串,要求该子串能够被分割成尽可能多的相同的字符串,若有多个符合要求的子串,输出字典序最小的那个。...

POJ 3693 - Maximum repetition substring (后缀数组)

Maximum repetition substring Time Limit: 1000MS   Memory Limit: 65536K Total Submiss...

【POJ】3693 Maximum repetition substring 【后缀数组——求最长连续重复字串】

传送门:【POJ】3693 Maximum repetition substring 题目分析:这个主要是看后缀数组的神论文了解的。。。。 对于枚举的长度L,如果存在连续重复子串,则对于s...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)