SPOJ 694 不重复子串
来源:互联网 发布:中国内审网络培训 编辑:程序博客网 时间:2024/05/21 10:23
按照sa数组的后缀字典序进行判断 每个串插入的时候应该有L个不同的子串(L为长度)
那么我们只要减去前面和它相同的重复前缀就可以算出加入这一条增加子串个数
那么就是 height[i]
论文水题 估计是要找变形了
#include <cstdio>#include <cstring>#define maxn 222222#define ll long long#define mid ((l+r)>>1)char s[maxn];int n,m,sa[maxn],rank[maxn],height[maxn];int wa[maxn],wb[maxn],ws[maxn],wv[maxn];int max(int a,int b){return a>b?a:b;}int min(int a,int b){return a<b?a:b;}inline bool cmp(int *r,int a,int b,int l){ return (r[a] == r[b]) && (r[a+l] == r[b+l]);}inline void da(int n,int m){ int i,j,p,*x=wa,*y=wb,*t; memset(ws,0,sizeof(ws)); for (i=0;i<n;++i) ws[x[i]=s[i]]++; for (i=1;i<m;++i) ws[i]+=ws[i-1]; for (i=n-1;i>=0;--i) sa[--ws[x[i]]]=i; for (j=1,p=1;p<n;j<<=1,m=p) { for (p=0,i=n-j;i<n;++i) y[p++]=i; for (i=0;i<n;++i) if (sa[i] >= j) y[p++]=sa[i]-j; for (i=0;i<n;++i) wv[i]=x[y[i]]; for (i=0;i<m;++i) ws[i]=0; for (i=0;i<n;++i) ws[wv[i]]++; for (i=1;i<m;++i) ws[i]+=ws[i-1]; for (i=n-1;i>=0;--i) sa[--ws[wv[i]]]=y[i]; for (t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;++i) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; }}inline void calcheight(){ int i,j,k=0; for (i=1;i<=n;++i) rank[sa[i]]=i; for (i=0;i<n;height[rank[i++]]=k) for (k?k--:0,j=sa[rank[i]-1];s[i+k]==s[j+k];k++);}//sa:1--strlen(s+'#')=n//height:2--nvoid print(){ for(int i=1;i<=n;++i){ printf("%d %d ",i,sa[i]); for(int j=sa[i];j<n;++j){ printf("%c",s[j]); } printf("\n"); } printf("\n"); for(int i=1;i<=n;++i){ printf("i:%d h:%d\n",i,height[i]); } printf("\n");}int main(){ int t;scanf("%d",&t); while(t--){ scanf("%s",s); n=(int)strlen(s); s[n]='#'; s[++n]='\0'; da(n+1,255); calcheight(); // print(); int ans=0; for(int i=2;i<=n;++i){ int tmp=(n-sa[i]-1)-height[i];// printf("%d %d %d \n",sa[i],height[i],tmp); ans+=tmp; } printf("%d\n",ans); } return 0;}
0 0
- SPOJ 694 不重复子串
- SPOJ 694 Distinct Substrings(SA 统计不重复子串个数)
- SPOJ 705(后缀数组求单个子串的不重复子串个数)
- spoj 694 不相同的子串的个数
- SPOJ 694,705(不相同的子串个数)
- SPOJ 694 Distinct Substrings + SPOJ 705 New Distinct Substrings (可重叠不相同子串个数)
- SPOJ 694 / SPOJ DISUBSTR Distinct Substrings【后缀数组】不相同的子串的个数
- 最长不重复子串
- 最长不重复子串
- 最长不重复子串
- 最长不重复子串
- 最长不重复子串
- 最长不重复子串
- 最长不重复子串
- 最长不重复子串
- 最长不重复子串
- 最长不重复子串
- 最长不重复子串
- Linux 服务器模型
- 找出带环单向链表的环入口(交点)
- 移动游戏开发 - 享受空闲时间用手机游戏
- project euler-34
- 关于set rowcount和@@rowcount
- SPOJ 694 不重复子串
- Ruby on Rails Tutorial第三章关于$ bundle exec respec 出错的问题的解决方案
- C中的volatile用法
- No matching code signing identity found
- 移动横幅造物主审查 - 最简单的指南对手机广告
- Base64与mime
- 神奇的镜盒
- ulipad python解释器设置问题
- jquery学习笔记-文本框的占位字符与ajax自动补全提示框