HDU 5769 Substring
Problem Description
?? 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.
Input
The first line of the input gives the number of test cases T;T test cases follow.
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.
Output
For each test case, output one line containing “Case #x: y”(without quotes), where x is the test case number(starting from 1) and y is the answer you get for that case.
Sample Input
2
a
abc
b
bbb
Sample Output
Case #1: 3
Case #2: 3
Hint
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.
题解
见 http://bestcoder.hdu.edu.cn/blog/2016-multi-university-training-contest-4-solutions-by-fzu/ 的 1006
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
/* Author : WNJXYK Problem : HDU 5769 Blog : http://wnjxyk.cn Date : 2016.7.30 */ #include<cstdio> #include<cstdlib> #include<ctime> #include<iostream> #include<algorithm> #include<cstring> #include<cmath> #include<set> #include<vector> #include<map> using namespace std; const int Maxn=100000; inline void radix(int str[],int pos[],int sa[],int n,int m){ static int cnt[Maxn+5]; memset(cnt,0,sizeof(cnt)); for (int i=0;i<n;i++) cnt[str[pos[i]]]++; for (int i=1;i<=m;i++) cnt[i]+=cnt[i-1]; for (int i=n-1;i>=0;i--) sa[--cnt[str[pos[i]]]]=pos[i]; } int sa[Maxn+5]; inline void SA(int str[],int sa[],int n,int m){ static int rnk[Maxn+5],a[Maxn+5],b[Maxn+5]; for (int i=0;i<n;i++) rnk[i]=i; radix(str,rnk,sa,n,m); rnk[sa[0]]=0; for (int i=1;i<n;i++) rnk[sa[i]] = rnk[sa[i-1]] + (str[sa[i]]!=str[sa[i-1]]); for (int k=1;k<=n;k<<=1){ for (int j=0;j<n;j++){ a[j]=rnk[j]+1; b[j]=(j+k>=n?0:rnk[j+k]+1); sa[j]=j; } radix(b,sa,rnk,n,n); radix(a,rnk,sa,n,n); rnk[sa[0]]=0; for (int i=1;i<n;i++) rnk[sa[i]] = rnk[sa[i-1]] + (a[sa[i]]!=a[sa[i-1]] || b[sa[i]]!=b[sa[i-1]]); } } int height[Maxn+5],rnk[Maxn+5]; inline void getHeight(int str[],int sa[],int rnk[],int height[],int n){ for (int i=0;i<n;i++) rnk[sa[i]]=i; int k=0; height[0]=0; for (int i=0;i<n;i++){ k=(k==0?0:k-1); if (rnk[i]!=0) while(str[i+k]==str[sa[rnk[i]-1]+k]) k++; height[rnk[i]]=k; } } char x[10]; char str[Maxn+5]; int istr[Maxn+5]; int len; int nxt[Maxn+5]; inline void solve(int T){ scanf("%s%s",x,str); len=strlen(str); //cout<<str<<endl; for (int i=0;i<len;i++) istr[i]=str[i]-'a'+1; SA(istr,sa,len,26); getHeight(istr,sa,rnk,height,len); int pre=len; for (int i=len;i>=0;i--){ if (str[i]==x[0]) pre=i; nxt[i]=pre; } long long Ans=0; for (int i=0;i<len;i++) Ans += len - max(nxt[sa[i]],sa[i]+height[i]); /*for (int i=0;i<len;i++) printf("%d ",sa[i]); printf("\n"); for (int i=0;i<len;i++) printf("%d ",height[i]); printf("\n"); for (int i=1;i<=len;i++) printf("%d ",nxt[i]); printf("\n"); */ printf("Case #%d: %I64d\n",T,Ans); } int main(){ //freopen("in.txt","r",stdin); int T; scanf("%d",&T); for (int i=1;i<=T;i++) solve(i); return 0; } |

原文链接:HDU 5769 Substring
WNJXYKの博客 版权所有,转载请注明出处。
还没有任何评论,你来说两句吧!