zoukankan      html  css  js  c++  java
  • CF427D Match & Catch(后缀数组)

    CF427D Match & Catch

    我其实很疑惑,为什么全网没人用 SA?这个题用 SA 不是巨水吗?我洗个澡就做出来了

    我们可以用传统拼接字符串的方式拼接一下字符串,求一遍 SA 和 height 数组。

    然后呢?其实很简单,题目让我们求的是最短的满足各只出现一次的连续公共字串。好,我们知道对于 height 数组,如果一个子串只在两个串中各出现一次,一定是一个“峰值”,即如 \(height_{x-1}<height_x>height_{x+1}\)。那么这时候我们可由取到的最短的串是多长?我们只要比两边的串长一点就够了,因此是 \(\max(height_{x-1},height_{x+1})+1\)。一句话答案:

    \[ans=\min\limits_{x\in (1,n)\operatorname{and}height_{x-1}<height_x>height_{x+1}} {\{\max(height_{x-1},height_{x+1})+1}\} \]

    没有满足条件的 \(x\),就输出 \(-1\)

    时间复杂度 \(O(n \log n+n)\)

    //Don't act like a loser.
    //This code is written by huayucaiji
    //You can only use the code for studying or finding mistakes
    //Or,you'll be punished by Sakyamuni!!!
    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    
    int read() {
    	char ch=getchar();
    	int f=1,x=0;
    	while(ch<'0'||ch>'9') {
    		if(ch=='-')
    			f=-1;
    		ch=getchar();
    	}
    	while(ch>='0'&&ch<='9') {
    		x=x*10+ch-'0';
    		ch=getchar();
    	}
    	return f*x;
    }
    
    const int MAXN=2e5+10; 
    
    int n,m;
    int sa[MAXN],rnk[MAXN],height[MAXN],tmp[MAXN],a[MAXN],b[MAXN],cnt[MAXN],calc[MAXN],bel[MAXN];
    char s[MAXN];
    
    void bucket_sort(int v[]) {
    	fill(cnt,cnt+m+1,0);
    	for(int i=1;i<=n;i++) {
    		cnt[v[i]+1]++;
    	}
    	for(int i=1;i<=m;i++) {
    		cnt[i]+=cnt[i-1];
    	}
    	for(int i=1;i<=n;i++) {
    		tmp[++cnt[v[sa[i]]]]=sa[i];
    	}
    	for(int i=1;i<=n;i++) {
    		sa[i]=tmp[i];
    	}
    }
    
    void get_sa() {
    	for(int i=1;i<=n;i++) {
    		rnk[i]=tmp[i]=s[i];
    		sa[i]=i;
    	}
    	sort(tmp+1,tmp+n+1);
    	m=unique(tmp+1,tmp+n+1)-tmp-1;
    	for(int i=1;i<=n;i++) {
    		rnk[i]=lower_bound(tmp+1,tmp+m+1,rnk[i])-tmp;
    	}
    	
    	for(int l=1;l<n;l<<=1) {
    		for(int i=1;i<=n;i++) {
    			a[i]=rnk[i];
    			b[i]=(i+l<=n? rnk[i+l]:0);
    		}
    		bucket_sort(b);
    		bucket_sort(a);
    		
    		m=0;
    		for(int i=1;i<=n;i++) {
    			if(a[sa[i]]!=a[sa[i-1]]||b[sa[i]]!=b[sa[i-1]]) {
    				m++;
    			}
    			rnk[sa[i]]=m;
    		}
    	}
    }
    
    void get_height() {
    	int h=0;
    	for(int i=1;i<=n;i++) {
    		if(h) {
    			h--;
    		}
    		if(rnk[i]==1) {
    			continue;
    		}
    		
    		int p=i+h;
    		int q=sa[rnk[i]-1]+h;
    		
    		while(p<=n&&q<=n&&s[p]==s[q]) {
    			p++;
    			q++;
    			h++;
    		}
    		height[rnk[i]]=h;
    	}
    }
    
    int solve() {
    	int ans=1e9+10;
    	bool flag=0;
    	
    	for(int i=2;i<=n;i++) {
    		if(height[i]>height[i-1]&&height[i]>height[i+1]) {
    			if(bel[sa[i]]!=bel[sa[i-1]]) {
    				ans=min(max(height[i-1],height[i+1])+1,ans);
    				flag=1;
    			}
    		}
    	}
    	
    	return flag? ans:-1;
    }
    
    signed main() {
    	scanf("%s",s+1);
    	n=strlen(s+1);
    	for(int i=1;i<=n;i++) {
    		bel[i]=1;
    	}
    	s[n+1]='$';
    	scanf("%s",s+n+2);
    	n=strlen(s+1);
    	for(int i=1;i<=n;i++) {
    		if(!bel[i]&&s[i]!='$') {
    			bel[i]=2;
    		}
    	}
    		
    	get_sa();
    	get_height();
    	
    	printf("%lld\n",solve());
    	return 0;
    }
    
    
  • 相关阅读:
    poj3107 Godfather
    poj1655 Balancing Act
    bzoj2073 PRZ
    bzoj1688 疾病管理
    BZOJ——1607: [Usaco2008 Dec]Patting Heads 轻拍牛头
    BZOJ——1606: [Usaco2008 Dec]Hay For Sale 购买干草
    BZOJ——1649: [Usaco2006 Dec]Cow Roller Coaster
    BZOJ——2096: [Poi2010]Pilots
    洛谷—— P1785 漂亮的绝杀
    NOIP 2012 提高组 DAY1 T2 国王游戏
  • 原文地址:https://www.cnblogs.com/huayucaiji/p/CF427D.html
Copyright © 2011-2022 走看看