hdu 5769 后缀数组
来源:互联网 发布:centos下安装jdk1.8 编辑:程序博客网 时间:2024/05/22 06:46
?? is practicing his program skill, and now he is given a string, he has to calculate the total number of its distinct substrings.
But ?? thinks that is too easy, he wants to make this problem more interesting.
?? likes a character X very much, so he wants to know the number of distinct substrings which contains at least one X.
However, ?? is unable to solve it, please help him.
But ?? thinks that is too easy, he wants to make this problem more interesting.
?? likes a character X very much, so he wants to know the number of distinct substrings which contains at least one X.
However, ?? is unable to solve it, please help him.
Each test case is consist of 2 lines:
First line is a character X, and second line is a string S.
X is a lowercase letter, and S contains lowercase letters(‘a’-‘z’) only.
T<=30
1<=|S|<=10^5
The sum of |S| in all the test cases is no more than 700,000.
2 a abc b bbb
Case #1: 3 Case #2: 3
In first case, all distinct substrings containing at least one a: a, ab, abc.In second case, all distinct substrings containing at least one b: b, bb, bbb.
问所给串的含有所给字符的不同子串有多少个
思路:
首先预处理出每个后缀后边最近的所给字符的位置,然后对主串处理出后缀数组
那么对于后缀sa[i]来说,他对结果的贡献就是
n-max(sa[i]+height[i],f[sa[i]])
这个公式还是很容易懂得,满足两种情况
1.前边后缀已经算过的不再计算(用height数组)
2.包含所给字符
ac代码:
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int mx=200100;char st[mx];int s[mx],sa[mx],t[mx],t2[mx],c[mx],n;int ran[mx],height[mx];void build_sa(int m){ int i,*x=t,*y=t2; for (i=0;i<m;i++) c[i]=0; for (i=0;i<n;i++) c[x[i]=s[i]]++; for (i=1;i<m;i++) c[i]+=c[i-1]; for (i=n-1;i>=0;i--) sa[--c[x[i]]]=i; for (int k=1;k<=n;k<<=1) { int p=0; for (i=n-k;i<n;i++) y[p++]=i; for (i=0;i<n;i++) if (sa[i]>=k) y[p++]=sa[i]-k; for (i=0;i<m;i++) c[i]=0; for (i=0;i<n;i++) c[x[y[i]]]++; for (i=1;i<m;i++) c[i]+=c[i-1]; for (i=n-1;i>=0;i--) sa[--c[x[y[i]]]]=y[i]; swap(x,y); p=1; x[sa[0]]=0; for (i=1;i<n;i++) 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; for (i=0;i<n;i++) ran[sa[i]]=i; for (i=0;i<n;i++) { if (k) k--; int j=sa[ran[i]-1]; while (s[i+k]==s[j+k]) k++; height[ran[i]]=k; }}char a[5];int f[mx];int main(){ int x; scanf("%d",&x); int cas=0; while(x--) { scanf("%s%s",a,st); int len=strlen(st); int flag=len; for(int i=len-1;i>=0;i--) { if(st[i]==a[0]) flag=i; f[i]=flag; } n=len+1; for(int i=0;i<len;i++) s[i]=st[i]-'a'+1; s[len]=0; build_sa(30); getHeight(); long long ans=(long long)len-max(sa[1],f[sa[1]]); for(int i=2;i<=len;i++) { ans+=(long long)len-max(sa[i]+height[i],f[sa[i]]); } printf("Case #%d: %lld\n",++cas,ans); }}
阅读全文
0 0
- HDU 5769 后缀数组
- HDU 5769 (后缀数组)
- hdu 5769 后缀数组
- HDU 5769后缀数组
- hdu 5769-后缀数组
- hdu 5769 后缀数组
- HDU 5769 Substring(后缀数组)
- hdu-5769-Substring-后缀数组
- hdu 5769 Substring 后缀数组
- HDU 5769 Substring(后缀数组)
- HDU 5769 Substring(后缀数组)
- HDU 5769 Substring (后缀数组)
- HDU 5769 后缀数组+二分
- Hdu-5769 Substring (SA后缀数组)
- HDU 5769 Substring(后缀数组)
- HDU 5769 Substring (后缀数组)
- HDU-5769-Substring(后缀数组)
- HDU 5769 Substring 多校赛 (后缀数组)
- D3D 天空盒实现
- 嵌入式Linux入门10:应用层编程应用和分类
- How to Install Review Board on Ubuntu 16.04
- JSON在Javascript中的使用(eval和JSON.parse的区别)
- JavaScript总结2
- hdu 5769 后缀数组
- 一次完整的浏览器请求响应过程
- Bealegbone-black学习笔记
- HDU 3691 Nubulsa Expo
- 数据结构与算法 二分法查找【Python与C】的实现
- 经纬度的正则表达式
- DNS与TCP、UDP协议
- [LibreOJ β Round #4]子集
- JavaScript 书写方式与注释