Ural 1590. Bacon’s Cipher 后缀数组
2013-07-27 21:15
351 查看
1590. Bacon’s Cipher
Time limit: 1.0 secondMemory limit: 64 MB
Programmer Vasya was down on his luck. Instead of a vacation, he was sent to a scientific conference.
“It is necessary to increase your competence,” his boss said, “it’s an important conference on cryptography, and it’s held in France, where they used encryption in the days of de Richelieu and cracked
codes in the days of Viete.”
One of the talks at the conference was about the attempts to solve Bacon’s ciphers. The speaker proposed a hypothesis that the key to Bacon’s secrets could be found if all possible substrings of Bacon’s
works were analyzed.
“But there are too many of them!” Vasya expressed his astonishment.
“Not as many as you think,” the speaker answered, “count them all and you’ll see it yourself.”
That evening Vasya found on the Web the complete set of Bacon’s works. He wrote a program that converted the texts into one long string by removing all linebreaks, spaces, and punctuation marks. And
now Vasya is confused because he doesn’t know how to calculate the number of different substrings of this string.
Input
You are given a nonempty string consisting of lowercase English letters. The string is no longer than 5000 symbols.Output
Output the number of different substrings of this string.Sample
input | output |
---|---|
aaba | 8 |
Problem Source: ACM ICPC 2007–2008. NEERC. Eastern Subregion. Yekaterinburg, October 27, 2007
/** 2013_7_27 * * Ural 1590. Bacon’s Cipher * 所有子串中不相同的个数 * 后缀数组对后缀排序然后再进行后缀讨论 * 倍增算法 r为待匹配数组 n为总长度 m为字符范围 * */ #include <stdio.h> #include <stdlib.h> #include <string.h> int const N = 5005; int wa , wb , ws , wv ; int rank , sa , height , r , n, k; int cmp( int* r, int a, int b, int L ) { return r[a]== r[b] && r[a+ L]== r[b+ L]; } void da( int* r, int* sa, int n, int m ) { int i, j, p, *x= wa, *y= wb, *t; for( i= 0; i< m; ++i ) ws[i]= 0; for( i= 0; i< n; ++i ) ws[ x[i]= r[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*= 2, 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]; t= x, x= y, y= t, p= 1; x[ sa[0] ]= 0; for( i= 1; i< n; ++i ) x[ sa[i] ]= cmp( y, sa[i-1], sa[i], j )? p- 1: p++; } } void callheight( int* r, int*sa, int n ) { 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]; r[i+k]== r[j+k]; k++ ); } char s[5005]; int main() { int i, ans; scanf("%s", s); n = strlen(s); for(i = 0; i < n; i ++) r[i] = (int)s[i]; da(r, sa, n + 1, 265); callheight( r, sa, n ); ans = n*(n+1)/2; for(i = 1; i <= n; i ++) ans -= height[i]; printf("%d\n", ans); return 0; }
相关文章推荐
- URAL 1297 Palindrome 后缀数组 或 Manacher 求最长回文子串
- URAL 1517 Freedom of Choice 后缀数组 入门
- URAL 1297:后缀数组求最长回文串
- ural 1297. Palindrome后缀数组求最长回文子串
- Ural1517 Freedom of choice, 后缀数组,最长公共子串
- URAL 1517. Freedom of choice(后缀数组:最长公共连续子串)
- BZOJ_1031_[JSOI2007]字符加密Cipher_后缀数组
- URAL 1297 后缀数组:求最长回文子串
- 【后缀数组|最长回文子串】URAL-1297 Palindrome
- 后缀数组——bzoj 1031: [JSOI2007]字符加密Cipher
- Ural 1517. Freedom of Choice 后缀数组
- Ural1297(Palindrome)求最长回文子串(后缀数组)
- ural 1297 O(nlogn) 后缀数组求最长回文字串
- URAL 1297. Palindrome(后缀数组 求最长回文子串)
- 后缀数组 - 求最长回文子串 + 模板题 --- ural 1297
- 后缀数组(最长回文字串)ural1297
- URAL 1517 Freedom of Choice(后缀数组,最长公共字串)
- ural 1297 Palindrome (后缀数组 最长回文)
- URAL 1297 Palindrome(后缀数组求最长回文子串)
- ural -1297. Palindrome----后缀数组解决最长回文串的问题