SPOJ DISUBSTR 后缀数组
来源:互联网 发布:知乎 陈廖宇 编辑:程序博客网 时间:2024/06/12 18:31
题意
有T个字符串,问每个字符串有多少不同的子串。
题解
后缀数组模板题,基本上模板套上去就能AC。当然了,还是有点变化的。关于后缀数组的题,首先观察Height特征。
可以发现,字符子串数量之和即为后缀长度之和。不过,子串有重复的,需要去重。观察height数组就会发现,height数组记录的就是两个后缀之间重复的前缀数量。因此后缀长度-height求和就可以了。
注意事项
第一次写后缀数组,忘记加尾字符$了,所以一直过不了样例,ORZ。。
代码
#include <iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<string>#include<set>#include<map>#include<bitset>#include<stack>#include<string>#pragma comment(linker,"/STACK:102400000,102400000")#define UP(i,l,h) for(int i=l;i<h;i++)#define DOWN(i,h,l) for(int i=h-1;i>=l;i--)#define W(a) while(a)#define MEM(a,b) memset(a,b,sizeof(a))#define LL long long#define INF 0x3f3f3f3f#define MAXN 50010#define MOD 1000000007#define EPS 1e-3using namespace std;struct Node { int to,val; Node(int to,int val):to(to),val(val) {}};char s[MAXN];int sa[MAXN],t[MAXN],t2[MAXN],c[MAXN],n,rk[MAXN],height[MAXN];void build_sa(int m) { int i,*x=t,*y=t2; UP(i,0,m) c[i]=0; UP(i,0,n) c[x[i]=s[i]]++; UP(i,1,m) c[i]+=c[i-1]; DOWN(i,n,0) sa[--c[x[i]]]=i; for(int k=1; k<=n; k<<=1) { int p=0; UP(i,n-k,n) y[p++]=i; UP(i,0,n) if(sa[i]>=k) y[p++]=sa[i]-k; UP(i,0,m) c[i]=0; UP(i,0,n) c[x[y[i]]]++; UP(i,0,m) c[i]+=c[i-1]; DOWN(i,n,0) sa[--c[x[y[i]]]]=y[i]; swap(x,y); p=1; x[sa[0]]=0; UP(i,1,n) x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k]?p-1:p++; if(p>=n) break; m=p; }}void getHeight(){ int i,j,k=0; UP(i,0,n) rk[sa[i]]=i; UP(i,0,n-1){ if(k) k--; int j=sa[rk[i]-1]; W(s[i+k]==s[j+k]) k++; height[rk[i]]=k; }}int main() { int t; scanf("%d",&t); W(t--) { scanf("%s",s); n=strlen(s); build_sa(128); getHeight(); int ans=0; UP(i,1,n) { ans+=(n-1-sa[i]-height[i]); } printf("%d\n",ans); }}
阅读全文
0 0
- SPOJ DISUBSTR(后缀数组)
- SPOJ DISUBSTR 后缀数组
- SPOJ DISUBSTR 后缀数组
- SPOJ 694 DISUBSTR Distinct Substrings 后缀数组
- [SPOJ DISUBSTR]Distinct Substrings(后缀数组)
- SPOJ DISUBSTR Distinct Substrings (后缀数组)
- 【SPOJ-DISUBSTR】Distinct Substrings【后缀数组】
- 【SPOJ DISUBSTR】Distinct Substrings 后缀数组
- SPOJ DISUBSTR Distinct Substrings(后缀数组)
- SPOJ DISUBSTR Distinct Substrings 后缀数组子串个数
- spoj 694 DISUBSTR - Distinct Substrings (后缀数组)
- SPOJ 694 / SPOJ DISUBSTR Distinct Substrings【后缀数组】不相同的子串的个数
- SPOJ - DISUBSTR Distinct Substrings(后缀数组求不相同的子串个数)
- SPOJ DISUBSTR - Distinct Substrings(后缀数组[不相同的子串的个数])
- SPOJ DISUBSTR-----后缀数组求串的子串的个数
- SPOJ DISUBSTR
- SPOJ DISUBSTR
- SPOJ694--- DISUBSTR - Distinct Substrings(后缀数组)
- Android折线图
- 漫画算法:最小栈的实现
- 【算法入门竞赛经典】【7.2枚举排列】
- PHP项目中可能用到的函数(持续更新)
- django基础之study
- SPOJ DISUBSTR 后缀数组
- idea中Hibernate错误:无法解析表
- #define命令的一些高级用法
- PASCAL Visual Object Class --- PASCAL VOC数据集 (最后附deeplab数据集)
- ubuntu下设置更新源代理
- 浅析Linux命令之cat
- 测手速小游戏
- c#多线程 task的使用
- html5新增表单属性