zoukankan      html  css  js  c++  java
  • 不同子串个数

    I.不同子串个数

    后缀数组在处理子串问题时往往有奇效,因为后缀的前缀即是子串,而后缀数组正是按照前缀排序的后缀

    回到本题。因为后缀的前缀是子串,则一条后缀与其它所有后缀的LCP的最长长度,即是这条后缀的前缀子串中所有被重复计数的串的数量。

    我们掏出求得的\(ht\)数组。初学SA时大家一定接触过一个重要的\(\text{LCP Lemma}\),即\(\operatorname{LCP}(i,j)=\min\limits_{i\leq j\leq k}ht_j\)。我们考虑当前后缀与其它任何一条串的LCP,发现它的表达式都包含\(ht_i\),即\(ht_i\)即为LCP的最长长度。则只需要求出所有子串数量减去\(\sum\limits_{i=1}^{n}ht_i\)即可。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll res;
    int n,m,sa[1001000],rk[1001000],buc[1001000],x[1001000],y[1001000],ht[1001000];
    char s[1001000];
    void SA(){
    	for(int i=1;i<=n;i++)buc[x[i]=s[i]]++;
    	for(int i=1;i<=m;i++)buc[i]+=buc[i-1];
    	for(int i=n;i;i--)sa[buc[x[i]]--]=i;
    	for(int k=1;k<=n;k<<=1){
    		int num=0;
    		for(int i=n-k+1;i<=n;i++)y[++num]=i;
    		for(int i=1;i<=n;i++)if(sa[i]>k)y[++num]=sa[i]-k;
    		for(int i=0;i<=m;i++)buc[i]=0;
    		for(int i=1;i<=n;i++)buc[x[y[i]]]++;
    		for(int i=1;i<=m;i++)buc[i]+=buc[i-1];
    		for(int i=n;i;i--)sa[buc[x[y[i]]]--]=y[i],y[i]=0;
    		swap(x,y);
    		x[sa[1]]=1;
    		num=1;
    		for(int i=2;i<=n;i++)x[sa[i]]=(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k])?num:++num;
    		if(num==n)break;
    		m=num;
    	}
    }
    void HT(){
    	for(int i=1;i<=n;i++)rk[sa[i]]=i;
    	int k=0;
    	for(int i=1;i<=n;i++){
    		if(rk[i]==1)continue;
    		if(k)k--;
    		int j=sa[rk[i]-1];
    		while(j+k<=n&&i+k<=n&&s[j+k]==s[i+k])k++;
    		ht[rk[i]]=k;
    	}
    }
    int main(){
    	scanf("%d%s",&n,s+1),m='z';
    	SA(),HT();
    //	for(int i=0;i<n;i++)printf("%d ",sa[i]);puts("");
    	for(int i=1;i<=n;i++)res+=(n-sa[i]+1)-ht[i];
    	printf("%lld\n",res);
    	return 0;
    }
    

  • 相关阅读:
    Windows下tomcat进程监控批处理程序
    centos下利用mail命令进行邮件发送
    centos查看是否安装了某个软件
    tomcat监控,自动重启shell脚本
    mac终端命令大全介绍
    文件的编码是一个怎样的机制
    python中nltk的下载安装方式
    MySQL——修改root密码的4种方法(以windows为例)
    VNC轻松连接远程Linux桌面
    Linux 查看磁盘分区、文件系统、磁盘的使用情况相关的命令和工具介绍
  • 原文地址:https://www.cnblogs.com/Troverld/p/14602298.html
Copyright © 2011-2022 走看看