• spoj694 DISUBSTR


    不相同子串个数。
    参考那篇论文。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    int n, m, p, x[1005], y[1005], c[1005], sa[1005], rnk[1005], hei[1005];
    int ans, T;
    char s[1005];
    void getSa(){
    	s[n++] = 0;
    	for(int i=0; i<m; i++)	c[i] = 0;
    	for(int i=0; i<n; i++)	c[x[i]=s[i]]++;
    	for(int i=1; i<m; i++)	c[i] += c[i-1];
    	for(int i=n-1; i>=0; i--)	sa[--c[x[i]]] = i;
    	for(int j=1; p<n; j*=2, m=p){
    		p = 0;
    		for(int i=n-j; i<n; i++)	y[p++] = i;
    		for(int i=0; i<n; i++)	if(sa[i]>=j)	y[p++] = sa[i] - j;
    		for(int i=0; i<m; i++)	c[i] = 0;
    		for(int i=0; i<n; i++)	c[x[y[i]]]++;
    		for(int i=1; i<m; i++)	c[i] += c[i-1];
    		for(int i=n-1; i>=0; i--)	sa[--c[x[y[i]]]] = y[i];
    		swap(x, y);
    		x[sa[0]] = 0;
    		p = 1;
    		for(int i=1; i<n; i++)
    			if(y[sa[i-1]]==y[sa[i]] && y[sa[i-1]+j]==y[sa[i]+j])
    				x[sa[i]] = p - 1;
    			else
    				x[sa[i]] = p++;
    	}
    	n--;
    }
    void getHei(){
    	int h=0;
    	for(int i=1; i<=n; i++)	rnk[sa[i]] = i;
    	for(int i=0; i<n; i++){
    		if(h)	h--;
    		int j=sa[rnk[i]-1];
    		while(s[i+h]==s[j+h])	h++;
    		hei[rnk[i]] = h;
    	}
    }
    int main(){
    	cin>>T;
    	while(T--){
    		scanf("%s", s);
    		n = strlen(s);
    		m = 128;
    		p = ans = 0;
    		getSa();
    		getHei();
    		for(int i=1; i<=n; i++)
    			ans += n - sa[i] - hei[i];//想一想,为什么
    		printf("%d
    ", ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    matlab2016b和c# .net4.0混合编程
    有限元入门
    math.net 拟合
    excel 错误提示以及其他基础知识
    excel的小bug
    Servlet体系及方法
    Servlet学习笔记
    HTTP协议
    Tomcat
    反射
  • 原文地址:https://www.cnblogs.com/poorpool/p/8266767.html
Copyright © 2020-2023  润新知