zoukankan      html  css  js  c++  java
  • POJ3294 Life Forms(后缀数组)

    引用罗穗骞论文中的话:

    将n 个字符串连起来,中间用不相同的且没有出现在字符串中的字符隔开,求后缀数组。然后二分答案,用和例3 同样的方法将后缀分成若干组,判断每组的后缀是否出现在不小于k 个的原串中。这个做法的时间复杂度为O(nlogn)。

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<cstring>
    #include<cstdlib>
    
    using namespace std;
    const int N = 110008;
    int wa[N],wb[N],wv[N],ws0[N];
    int val[N], sum[N], tp1[N], tp2[N];
    int sa[N], rank[N], height[N];
    int hs[N];
    
    char tp[1008];
    int str[N];
    bool vis[1000];
    
    vector<int> v;
    
    int cmp(int *r,int a,int b,int l)
    {return r[a]==r[b]&&r[a+l]==r[b+l];}
    void da(int *r,int *sa,int n,int m)
    {
         int i,j,p,*x=wa,*y=wb,*t;
         for(i=0;i<m;i++) ws0[i]=0;
         for(i=0;i<n;i++) ws0[x[i]=r[i]]++;
         for(i=1;i<m;i++) ws0[i]+=ws0[i-1];
         for(i=n-1;i>=0;i--) sa[--ws0[x[i]]]=i;
         for(j=1,p=1;p<n;j*=2,m=p)
         {
           for(p=0,i=n-j;i<n;i++) y[p++]=i;
           for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;
           for(i=0;i<n;i++) wv[i]=x[y[i]];
           for(i=0;i<m;i++) ws0[i]=0;
           for(i=0;i<n;i++) ws0[wv[i]]++;
           for(i=1;i<m;i++) ws0[i]+=ws0[i-1];
           for(i=n-1;i>=0;i--) sa[--ws0[wv[i]]]=y[i];
           for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)
           x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
         }
         return;
    }
    void calheight(int *r,int *sa,int n)
    {
         int i,j,k=0;
         for(i=1;i<=n;i++) rank[sa[i]]=i;
         for(i=0;i<n;height[rank[i++]]=k)
         for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++);
         return;
    }
    
    bool check(int m, int n, int num){
    	memset(vis , 0, sizeof(vis));
    	int cnt = 0;
    	int size = 0;
    	for(int i = 1; i <= n ;i++){
    		if(height[i] >= m){//分组,同组内计数
    		    if(!vis[hs[ sa[i] ]]){
    				cnt++;
    				vis[hs[ sa[i] ]] = 1;
    			}
    
    			if(!vis[hs[ sa[i - 1] ]]){//不同组
    				cnt++;
    				vis[hs[ sa[i - 1] ]] = 1;
    			}
    
    		}else{
    			if(cnt > num){
    				if(size == 0){
    					v.clear();
    				}
    				size++;
    				v.push_back(sa[i - 1]);
    			}
    			cnt = 0;
                memset(vis, 0 , sizeof(vis));
    
    		}
    	}
    	if(size){
    		return true;
    	}else{
    		return false;
    	}
    
    }
    
    
    int main(){
        int k;
        bool flag = 0;
        while(~scanf("%d", &k ) && k){
                v.clear();
        	int n = 0;
        	int mini = 100000000;
        	for(int t = 0; t < k; t++){
        		scanf("%s", tp);
        		int len = strlen(tp);
        		mini = min(mini, len);
        		for(int i = n, j = 0; j < len; i++, j++){
        			str[i]  = tp[j];
        			hs[i] = t;
        		}
        		n += len + 1;
        		if(t != k - 1){
        			str[n - 1] = t + 130;
        		}
        	}
        	n--;
        	str[n] = 0;
            da(str, sa , n + 1 , 256);
        	calheight(str, sa, n);
        	int l = 1, r = mini;
        	int ans = 0;
        	while(l <= r){
        		int m = (l + r)>>1;
        		if(check(m, n, k / 2 )){
        			l = m + 1;
        			ans = m;
        		}else{
        			r = m - 1;
        		}
        	}
        	if(flag){
        		printf("
    ");
        	}
        	flag = 1;
        	if(ans){
        		for(int i = 0; i < v.size(); i++){
        			int st = v[i];
        			for(int j = 0; j < ans; j++){
        				printf("%c", str[st + j]);
        			}
        			printf("
    ");
        		}
        	}else{
        		printf("?
    ");
        	}
    
        }
        return 0;
    }
    

      

  • 相关阅读:
    Educational Codeforces Round 86 (Rated for Div. 2) D. Multiple Testcases
    Educational Codeforces Round 86 (Rated for Div. 2) C. Yet Another Counting Problem
    HDU
    HDU
    HDU
    HDU
    Good Bye 2019 C. Make Good (异或的使用)
    Educational Codeforces Round 78 (Rated for Div. 2) C. Berry Jam
    codeforces 909C. Python Indentation
    codeforces1054 C. Candies Distribution
  • 原文地址:https://www.cnblogs.com/IMGavin/p/5733733.html
Copyright © 2011-2022 走看看