2016 Multi-University Training Contest 4 1006 Substring(后缀数组)
2016-09-08 15:47
453 查看
题意
给出一个字符X和一个字符串,求字符串的字串中,包含字符的不同字串有多少个。思路
很明显的后缀数组,但是要做一些变化,因为必须至少包含一个字符X,所以我们就记录一下对于每个sa[i],离他最近的X的位置为Loc[sa[i]],这个位置到sa[i]的距离和height[i]的最大值就是不可取的数量,然后用n减去sa[i]和上面那个值就是这个sa的可选数量,累加就是答案。代码
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; typedef int main_int; #define int ll const int N = 1e5+10; int wa , wb , ws , wv ; int ran , height ; bool 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; 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]; for (swap(x, y), 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++; } } void calheight(int r[], int sa[], int n) { int i, j, k = 0; for (i = 1; i <= n; ++i) ran[sa[i]] = i; for (i = 0; i < n; height[ran[i++]] = k) for (k?k--:0, j = sa[ran[i]-1]; r[i+k] == r[j+k]; k++); } int loc ; char str ; int 9a33 sa , n, r ; char ch[10]; main_int main() { int T,kas =1; //freopen("1006.in","r",stdin); //freopen("1006","w",stdout); scanf("%I64d", &T); while(T--){ scanf("%s", ch); scanf("%s", str); n = strlen(str); for(int i = 0; i < n; i++) { r[i] = (int)str[i]; } r = 0; loc = n; for(int i = n-1 ; i >= 0 ; i --){ if(str[i] == ch[0]) loc[i] = i; else loc[i] = loc[i+1]; } da(r, sa, n + 1, 128LL); calheight(r, sa, n); int ans = 0LL; for(int i = 1; i <= n; i++) { int tmp = max(loc[sa[i]] - sa[i], height[i]); ans += n - sa[i] - tmp; } printf("Case #%I64d: %I64d\n",kas ++,ans); } return 0; }
相关文章推荐
- 2016 Multi-University Training Contest 4 1006 Substring
- 欧拉定理——PowMod ( HDU 5728 )(2016 Multi-University Training Contest 1 1006)
- 2016 Multi-University Training Contest 2 1006 Fantasia (hdu5739) 【割点 无向图dfs树 树形dp】
- HDU 5769-->Substring-->2016 Multi-University Training Contest 4
- 2016 Multi-University Training Contest 8-1006 physics
- 2016 Multi-University Training Contest 1 1006 PowMod
- 2016 Multi-University Training Contest 1 -1006 PowMod
- [HDU5826] physics [2016 Multi-University Training Contest 8(2016多校联合训练8) 1006]
- 2016 Multi-University Training Contest 8 1006 physics (物理+数学)
- 2016 多校 Multi-University Training Contest 4 Substring
- 2016 Multi-University Training Contest 5 1003 Divide the Sequence (贪心)
- 2016 Multi-University Training Contest 1题解报告
- 2016 Multi-University Training Contest 1 题解(慢慢补)
- 2016 Multi-University Training Contest 1 1005 Necklace
- 2016 Multi-University Training Contest 1-1004---HDU 5726 GCD
- 2016 Multi-University Training Contest 2 1001 hdu 5734 暴力
- 2016 Multi-University Training Contest 2
- 2016 Multi-University Training Contest 2 1001 Acperience
- 2016 Multi-University Training Contest 2 It's All In The Mind
- hdu 5744(2016 Multi-University Training Contest 2)