zoukankan      html  css  js  c++  java
  • SPOJ-SUBST1 New Distinct Substrings(后缀数组)

    题目大意:判断总共有多少种不同的子串。

    题目分析:不同的子串数目为 Σ(后缀SA[i]的长度-height[i])。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    # define LL long long
    
    const int N=50000;
    
    char str[N+5];
    
    int n,SA[N+5],cnt[N+5];
    int rk[N+5],tSA[N+5];
    LL ans;
    
    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=130;
    	for(int i=0;i<m;++i) cnt[i]=0;
    	for(int i=0;i<n;++i) ++cnt[rk[i]=(int)str[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)
    			rk[SA[i]]=same(SA[i],SA[i-1],k)?p-1:p++;
    		if(p>=n) break;
    		m=p;
    	}
    }
    
    void getHeight()
    {
    	for(int i=0;i<n;++i) rk[SA[i]]=i;
    	ans=0;
    	int k=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&&str[i+k]==str[j+k]) ++k;
    		}
    		ans+=n-SA[i]-k;
    	}
    }
    
    int main()
    {
    	int T;
    	scanf("%d",&T);
    	while(T--)
    	{
    		scanf("%s",str);
    		n=strlen(str);
    		buildSA();
    		getHeight();
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    JSTL和EL
    SpringMVC 上传文件and过滤器
    SQLServer 大数据查询2
    SQLServer 大数据查询分析
    Oracle分页查询
    Oracle大数据常见优化查询
    Window 下面利用Oid 获取SNMP主机信息 以及计算方法
    window 下面安装net-snmp 简单网关协议
    显示一行省略文字的详细信息
    手机自动隐藏浏览器地址栏
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/5954653.html
Copyright © 2011-2022 走看看