HDU 3518Boring counting

来源:互联网 发布:淘宝店家进货渠道 编辑:程序博客网 时间:2024/05/22 04:38

Description

035 now faced a tough problem,his english teacher gives him a string,which consists with n lower case letter,he must figure out how many substrings appear at least twice,moreover,such apearances can not overlap each other. 
Take aaaa as an example.”a” apears four times,”aa” apears two times without overlaping.however,aaa can’t apear more than one time without overlaping.since we can get “aaa” from [0-2](The position of string begins with 0) and [1-3]. But the interval [0-2] and [1-3] overlaps each other.So “aaa” can not take into account.Therefore,the answer is 2(“a”,and “aa”). 

Input

The input data consist with several test cases.The input ends with a line “#”.each test case contain a string consists with lower letter,the length n won’t exceed 1000(n <= 1000).

Output

For each test case output an integer ans,which represent the answer for the test case.you’d better use int64 to avoid unnecessary trouble.

Sample Input

aaaaababcabbaaaaaa#

Sample Output

23

3

统计在一个串里出现两次以上且没有交集的子串有几个。

#include<set>#include<map>#include<ctime>#include<cmath>#include<stack>#include<queue>#include<bitset>#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<algorithm>#include<functional>#define rep(i,j,k) for (int i = j; i <= k; i++)#define per(i,j,k) for (int i = j; i >= k; i--)#define lson x << 1, l, mid#define rson x << 1 | 1, mid + 1, r#define fi first#define se second#define mp(i,j) make_pair(i,j)#define pii pair<int,int>using namespace std;typedef long long LL;const int low(int x) { return x&-x; }const double eps = 1e-8;const int INF = 0x7FFFFFFF;const int mod = 1e9 + 7;const int N = 2e5 + 10;const int read(){char ch = getchar();while (ch<'0' || ch>'9') ch = getchar();int x = ch - '0';while ((ch = getchar()) >= '0'&&ch <= '9') x = x * 10 + ch - '0';return x;}int T, m;struct Sa{char s[N];int rk[2][N], sa[N], h[N], w[N], now, n;int rmq[N][20], lg[N], bel[N];bool GetS(){return scanf("%s", s + 1), s[1] != '#';}void getsa(int z, int &m){int x = now, y = now ^= 1;rep(i, 1, z) rk[y][i] = n - i + 1;for (int i = 1, j = z; i <= n; i++)if (sa[i] > z) rk[y][++j] = sa[i] - z;rep(i, 1, m) w[i] = 0;rep(i, 1, n) w[rk[x][rk[y][i]]]++;rep(i, 1, m) w[i] += w[i - 1];per(i, n, 1) sa[w[rk[x][rk[y][i]]]--] = rk[y][i];for (int i = m = 1; i <= n; i++){int *a = rk[x] + sa[i], *b = rk[x] + sa[i - 1];rk[y][sa[i]] = *a == *b&&*(a + z) == *(b + z) ? m - 1 : m++;}}void getsa(int m){n = strlen(s + 1);rk[1][0] = now = sa[0] = s[0] = 0;rep(i, 1, m) w[i] = 0;rep(i, 1, n) w[s[i]]++;rep(i, 1, m) rk[1][i] = rk[1][i - 1] + (bool)w[i];rep(i, 1, m) w[i] += w[i - 1];rep(i, 1, n) rk[0][i] = rk[1][s[i]];rep(i, 1, n) sa[w[s[i]]--] = i;rk[1][n + 1] = rk[0][n + 1] = 0;//多组的时候容易出bugfor (int x = 1, y = rk[1][m]; x <= n && y <= n; x <<= 1) getsa(x, y);for (int i = 1, j = 0; i <= n; h[rk[now][i++]] = j ? j-- : j){if (rk[now][i] == 1) continue;int k = n - max(sa[rk[now][i] - 1], i);while (j <= k && s[sa[rk[now][i] - 1] + j] == s[i + j]) ++j;}}void getrmq(){h[n + 1] = h[1] = lg[1] = 0;rep(i, 2, n) rmq[i][0] = h[i], lg[i] = lg[i >> 1] + 1;for (int i = 1; (1 << i) <= n; i++){rep(j, 2, n){if (j + (1 << i) > n + 1) break;rmq[j][i] = min(rmq[j][i - 1], rmq[j + (1 << i - 1)][i - 1]);}}}int lcp(int x, int y){int l = min(rk[now][x], rk[now][y]) + 1, r = max(rk[now][x], rk[now][y]);return min(rmq[l][lg[r - l + 1]], rmq[r - (1 << lg[r - l + 1]) + 1][lg[r - l + 1]]);}void work(){getsa(300);int ans = 0;rep(i, 1, n){int L = INF, R = 0;rep(j, 2, n){if (h[j] >= i){L = min(L, min(sa[j - 1], sa[j]));R = max(R, max(sa[j - 1], sa[j]));}else{if (R - L >= i) ans++;L = INF;R = 0;}}ans += R - L >= i;}printf("%d\n", ans);}}sa;int main(){while (sa.GetS()) sa.work();return 0;}


0 0