zoukankan      html  css  js  c++  java
  • POJ-1743 Musical Theme(后缀数组)

    题目大意:给一个整数序列,找出最长的连续变化相同的、至少出现两次并且不相重叠一个子序列。

    题目分析:二分枚举长度进行判定。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    # define mid (l+(r-l)/2)
    
    const int N=20000;
    
    int SA[N+5],height[N+5];
    int *rk,*tSA;
    int n,a[N+5],cnt[N+5];
    
    bool same(int i,int j,int k)
    {
        if(tSA[i]!=tSA[j]) return false;
        if(i+k>=n&&j+k>=n) return true;
        if(i+k>=n&&j+k<n) return false;
        if(i+k<n&&j+k>=n) return false;
        return tSA[i+k]==tSA[j+k];
    }
    
    void buildSA()
    {
        int m=180;
        for(int i=0;i<m;++i) cnt[i]=0;
        for(int i=0;i<n;++i) ++cnt[rk[i]=a[i]];
        for(int i=1;i<m;++i) cnt[i]+=cnt[i-1];
        for(int i=n-1;i>=0;--i) SA[--cnt[rk[i]]]=i;
    	
        for(int k=1;k<n;k<<=1){
            int p=0;
            for(int i=n-k;i<n;++i) tSA[p++]=i;
            for(int i=0;i<n;++i) if(SA[i]>=k) tSA[p++]=SA[i]-k;
    
            for(int i=0;i<m;++i) cnt[i]=0;
            for(int i=0;i<n;++i) ++cnt[rk[tSA[i]]];
            for(int i=1;i<m;++i) cnt[i]+=cnt[i-1];
            for(int i=n-1;i>=0;--i) SA[--cnt[rk[tSA[i]]]]=tSA[i];
    
            swap(rk,tSA);
            p=1;
            rk[SA[0]]=0;
            for(int i=1;i<n;++i){
                if(same(SA[i],SA[i-1],k)) rk[SA[i]]=p-1;
                else rk[SA[i]]=p++;
            }
            if(p>=n) break;
            m=p;
        }
    }
    
    void getHeight()
    {
        for(int i=0;i<n;++i) rk[SA[i]]=i;
        int k=0;
        height[0]=0;
        for(int i=0;i<n;++i){
    		if(rk[i]==0) k=0;
    		else{
    			if(k) --k;
    			int j=SA[rk[i]-1];
    			while(i+k<n&&j+k<n&&a[i+k]==a[j+k]) ++k;
    			height[rk[i]]=k;
    		}
        }
    }
    
    bool ok(int x)
    {
    	int maxn=SA[0],minn=SA[0];
    	for(int i=1;i<n;++i){
    		if(minn+x<maxn) return true;
    		if(height[i]>=x){
    			maxn=max(maxn,SA[i]);
    			minn=min(minn,SA[i]);
    		}else{
    			maxn=minn=SA[i];
    		}
    	}
    	return minn+x<maxn;
    }
    
    void init()
    {
        rk=new int[n+5];
        tSA=new int[n+5];
    }
    
    void destroy()
    {
        delete []rk;
        delete []tSA;
    }
    
    int main()
    {
        while(scanf("%d",&n)&&n)
        {
            init();
            for(int i=0;i<n;++i){
                scanf("%d",a+i);
                --a[i];
            }
    		--n;
    		int temp=a[0];
    		for(int i=0;i<n;++i){
    			a[i]=a[i+1]-temp+87;
    			temp=a[i+1];
    		}
    		
            buildSA();
            getHeight();
    		
    		//二分枚举最短的不满足条件的
    		int l=4,r=n;
    		while(l<r){
    			if(ok(mid)) l=mid+1;
    			else r=mid;
    		}
    		printf("%d
    ",l>=5?l:0);
            destroy();
        }
        return 0;
    }
    

      

  • 相关阅读:
    WARNING OGG-00706 Failed to add supplemental log group on table
    Lucene&Solr框架之第一篇
    SSM框架整合之练习篇
    SpringMVC框架之第四篇
    SpringMVC框架之第三篇
    SpringMVC框架之第二篇
    SpringMVC框架之第一篇
    MyBatis框架之第三篇
    MyBatis框架之第二篇
    maven仓库之第二篇
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/5954156.html
Copyright © 2011-2022 走看看