zoukankan      html  css  js  c++  java
  • BZOJ.4566.[HAOI2016]找相同字符(后缀数组 单调栈)

    题目链接

    给定两个字符串,求它们有多少个相同子串。相同串的位置不同算多个。

    POJ3145简化版。
    后缀自动机做法见这儿,又快又好写(一下就看出差距了。。)

    //13712kb	4076ms
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    const int N=4e5+5;
    
    int n,rk[N],sa[N],sa2[N],tm[N],ht[N],bel[N],sk[N],val[N];
    char s[N];
    
    void Get_SA()
    {
    	int *x=rk,*y=sa2,m=30;
    	for(int i=0; i<=m; ++i) tm[i]=0;
    	for(int i=1; i<=n; ++i) ++tm[x[i]=s[i]-'a'+2];
    	for(int i=1; i<=m; ++i) tm[i]+=tm[i-1];
    	for(int i=n; i; --i) sa[tm[x[i]]--]=i;
    	for(int p=0,k=1; k<n; m=p,p=0,k<<=1)
    	{
    		for(int i=n-k+1; i<=n; ++i) y[++p]=i;
    		for(int i=1; i<=n; ++i) if(sa[i]>k) y[++p]=sa[i]-k;
    		for(int i=0; i<=m; ++i) tm[i]=0;
    		for(int i=1; i<=n; ++i) ++tm[x[i]];
    		for(int i=1; i<=m; ++i) tm[i]+=tm[i-1];
    		for(int i=n; i; --i) sa[tm[x[y[i]]]--]=y[i];
    
    		std::swap(x,y), p=x[sa[1]]=1;
    		for(int i=2; i<=n; ++i)
    			x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?
    
    p:++p;
    		if(p>=n) break;
    	}
    	for(int i=1; i<=n; ++i) rk[sa[i]]=i;
    	ht[1]=0;
    	for(int k=0,p,i=1; i<=n; ++i)
    	{
    		if(rk[i]==1) continue;
    		if(k) --k;
    		p=sa[rk[i]-1];
    		while(i+k<=n&&p+k<=n&&s[i+k]==s[p+k]) ++k;
    		ht[rk[i]]=k;
    	}
    }
    
    int main()
    {
    	scanf("%s",s+1); int l=strlen(s+1);
    	s[l+1]='a'-1, scanf("%s",s+2+l), n=strlen(s+1);
    	Get_SA();
    	for(int i=2; i<=n; ++i) bel[i]=sa[i]>l;
    	long long res=0,tmp;
    	val[0]=-1;
    	for(int top,t=0; t<=1; ++t)
    	{
    		tmp=0, top=0;
    		for(int i=2; i<=n; ++i)
    		{
    			if(bel[i]!=t) res+=tmp;
    			sk[++top]=bel[i]==t, val[top]=ht[i+1];
    			tmp+=(long long)sk[top]*val[top];
    			while(val[top-1]>=val[top])//>=比>要快啊 
    			{
    				--top;
    				tmp-=(long long)(val[top]-val[top+1])*sk[top];
    				val[top]=val[top+1], sk[top]+=sk[top+1];
    			}
    		}
    	}
    	printf("%lld",res);
    
    	return 0;
    }
    
  • 相关阅读:
    SimpleDateFormatter Java中的用法
    线性判别分析浅析及推导
    主成分分析(PCA)原理及推导
    浅说机器学习理论
    给“过拟合”下一个准确且规范的定义
    信息熵和Gini指数的关系
    WinRAR默认压缩格式ZIP
    批量学习和在线学习的区别
    LDA线性判别分析
    主成分分析(PCA)原理与实现
  • 原文地址:https://www.cnblogs.com/SovietPower/p/8573275.html
Copyright © 2011-2022 走看看