spoj 694 Distinct Substrings (后缀数组应用)
来源:互联网 发布:淘宝上怎样找高仿耐克 编辑:程序博客网 时间:2024/06/06 17:39
题意:
给出长度为n的串,求这个串中不通的子串个数。
题解:
首先我们分析,这种题应该从每个子串入手,每个子串肯定是后缀的前缀,所以分析后缀的一些关系。单独分析一个后缀能为不通子串个数贡献多少,如果按照SA的顺序不断计算出后缀,当要加入k这个后缀时,他的长度为n-SA[k],那么他可以贡献出的前缀也就是子串的个数肯定有n-SA[k],但是他和前一个后缀有重叠部分重叠部分的长度便是多计算的子串个数,于是减去height[k]。然后把所有后缀的n-SA[k]-height[k]加起来就是答案。
#include<iostream>#include<math.h>#include<stdio.h>#include<algorithm>#include<string.h>#include<vector>#include<queue>#include<map>#include<set>using namespace std;#define B(x) (1<<(x))typedef long long ll;const int oo=0x3f3f3f3f;const ll OO=1LL<<61;const int MOD=10007;const int maxn=1005;int rank[maxn],SA[maxn],height[maxn];int t1[maxn],t2[maxn],t3[maxn],cnt[maxn];char str[maxn];void Swap(int*& x,int*& y){ int *temp=x; x=y; y=temp;}int lcp(int t[],int a,int b,int l){ return t[a]==t[b]&&t[a+l]==t[b+l];}void build_SA(char s[],int len,int up){ int *k1=t1,*k2=t2,*r=t3; for(int i=0;i<up;i++)cnt[i]=0; for(int i=0;i<len;i++)cnt[k1[i]=s[i]]++; for(int i=1;i<up;i++)cnt[i]+=cnt[i-1]; for(int i=len-1;i>=0;i--)SA[--cnt[k1[i]]]=i; for(int d=1,p=0;p<len;d<<=1){ for(int i=len-d;i<len;i++)k2[p++]=i; for(int i=0;i<len;i++)if(SA[i]>=d)k2[p++]=SA[i]-d; for(int i=0;i<len;i++)r[i]=k1[k2[i]]; for(int i=0;i<up;i++)cnt[i]=0; for(int i=0;i<len;i++)cnt[r[i]]++; for(int i=1;i<up;i++)cnt[i]+=cnt[i-1]; for(int i=len-1;i>=0;i--)SA[--cnt[r[i]]]=k2[i]; Swap(k1,k2); k1[SA[0]]=0; p=1; for(int i=1;i<len;i++){ k1[SA[i]]= lcp(k2,SA[i-1],SA[i],d) ? p-1 : p++; } if(p>=len)return; up=p; p=0; }}void get_height(char s[],int len){ for(int i=1;i<=len;i++)rank[SA[i]]=i; for(int i=0,p=0;i<len;i++){ int j=SA[rank[i]-1]; while(s[i+p]==s[j+p])p++; height[rank[i]]=p; if(p)p--; }}int main(){ int T; scanf("%d",&T); while(T--){ scanf("%s",str); int len=strlen(str); str[len]='#'; build_SA(str,len+1,128); get_height(str,len); ll ans=0; for(int i=1;i<=len;i++){ ans+=len-SA[i]-height[i]; } printf("%I64d\n",ans); } return 0;}/***/
0 0
- spoj 694 Distinct Substrings (后缀数组应用)
- SPOJ 694 Distinct Substrings(后缀数组)
- 【后缀数组】【spoj 694】Distinct Substrings
- SPOJ 694 DISUBSTR Distinct Substrings 后缀数组
- spoj 694 Distinct Substrings(后缀数组)
- spoj 694 Distinct Substrings (后缀数组)
- SPOJ 694 Distinct Substrings 后缀数组 模板
- SPOJ 694 Distinct Substrings(后缀数组)
- spoj 694 Distinct Substrings 后缀数组
- SPOJ 694 Distinct Substrings 后缀数组
- Spoj 694 Distinct Substrings(后缀数组)
- SPOJ 694 Distinct Substrings <后缀数组>
- spoj 694 Distinct Substrings (后缀数组)
- |spoj 694|后缀数组|Distinct Substrings
- SPOJ 694 Distinct Substrings 后缀数组
- SPOJ 694 Distinct Substrings(后缀数组)
- SPOJ Distinct Substrings 后缀数组
- SPOJ 694. Distinct Substrings,705. New Distinct Substrings(后缀数组)
- 安装percona-toolkit-2.2.1.tar.gz
- python基础知识(1)——列表和元组
- uva11195(回溯+位运算)
- 【机器学习基础】验证
- iOS-iOS文件系统基础
- spoj 694 Distinct Substrings (后缀数组应用)
- percona工具使用一 pt-table-sync
- win7开启热点时“无法启动承载网络”的解决方法
- return换行也有错?javascript中return的设计缺陷
- 非递归地中序遍历BST
- [线段树] HDU 1166 - 敌兵布阵
- Android Studio 1.x版 签名key生成,查看key的sha1 和MD5 的方法
- 为什么mvc不是23种设计模式之一?
- 【BZOJ3888】【Usaco2015 Jan】Stampede 线段树判区间覆盖