1.Title Link . How many strings are different in nature? Different in nature is defined as: two strings are not equal.
2. This problem is actually very simple. From the perspective of suffix array, for each sa[i], we know that sa[i] represents the position of the suffix ranking I. assuming that it is j, then the length of the suffix is n-j. it has n-j prefixes, which are all substrings of this string. It can be proved that (all substrings can be generated from the prefixes of these suffixes. It can be proved that they are equal in quantity. But we can see from the definition of height array that height[i] represents lcp(sa[i],sa[i-1]), so I and i-1 will have common prefixes, which are repeated, subtraction is enough. So this question is very simple, ans=sigma(n-sa[i]-heigh[i]). Time complexity O(nlogn).
#include<bits/stdc++.h> #define ll long long using namespace std; const int MAXN = 2e5 + 10; int sa[MAXN], rnk[MAXN], rsort[MAXN], y[MAXN], wr[MAXN], height[MAXN]; char a[MAXN]; bool cmp(int a, int b, int len) { return wr[a] == wr[b] && wr[a + len] == wr[b + len]; } void get_SA(int m, int n) { for (int i = 1; i <= n; i++) rnk[i] = a[i - 1]; for (int i = 1; i <= n; i++) rsort[rnk[i]]++; for (int i = 1; i <= m; i++) rsort[i] += rsort[i - 1]; for (int i = n; i > 0; i--) sa[rsort[rnk[i]]--] = i; int len = 1, p = 0; while (p < n) { int k = 0; //y[i]: ranking by the second keyword, the position of the first keyword ranking as I for (int i = n - len + 1; i <= n; i++) y[++k] = i; for (int i = 1; i <= n; i++) if (sa[i] > len) y[++k] = sa[i] - len; for (int i = 1; i <= n; i++) wr[i] = rnk[y[i]]; //wr[i]: sort by the second keyword, ranking the first keyword of I memset(rsort, 0, sizeof(rsort)); for (int i = 1; i <= n; i++) rsort[wr[i]]++; for (int i = 1; i <= m; i++) rsort[i] += rsort[i - 1]; for (int i = n; i > 0; i--) sa[rsort[wr[i]]--] = y[i]; for (int i = 1; i <= n; i++) wr[i] = rnk[i]; p = 1; rnk[sa[1]] = 1; for (int i = 2; i <= n; i++) { if (!cmp(sa[i], sa[i - 1], len)) p++; rnk[sa[i]] = p; } m = p; len <<= 1; } } void get_height(int n) { int k = 0, j; for (int i = 1; i <= n; i++) { j = sa[rnk[i] - 1]; if (k) k--; while (a[j + k - 1] == a[i + k - 1]) k++; height[rnk[i]] = k; } } ll solve(int n) { ll ans = 0; for (int i = 1; i <= n; i++) ans += n + 1 - sa[i] - height[i]; return ans; } int main() { int len; scanf("%d", &len); scanf("%s", a); get_SA(300, len); get_height(len); printf("%lld", solve(len)); return 0; }