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 95 96 97 98
| #include <bits/stdc++.h> using namespace std; template <typename T> inline void read(T &a){ T w=1; a=0; char ch=getchar(); for(;ch < '0' || ch > '9';ch=getchar()) if(ch == '-') w=-1; for(;ch>='0'&&ch<='9';ch=getchar()) a=(a<<3)+(a<<1)+(ch^48); a*=w; } template <typename T> inline void ckmax(T &a, T b){a = a > b ? a : b;} template <typename T> inline void ckmin(T &a, T b){a = a < b ? a : b;} #define int long long #define fi first #define se second #define pb push_back #define mp make_pair #define mii map<int, int> #define pii pair<int, int> #define vi vector<int> #define Debug(x) cout << #x << " = " << x << endl #define For(i,l,r) for (int i = l; i <= r; ++i) #define foR(i,l,r) for (int i = l; i >= r; --i) #define ll long long const int N = 5e4 + 10, Blo = 256, Base = 1e6 + 3, Mod = 1e9 + 7; int pw[N]; struct Block { int h[Blo + 10], v[Blo + 10]; void upd (int x, int y) { v[x] = y; For (i, 1, Blo) h[i] = (1ll * h[i - 1] * Base + v[i]) % Mod; } } c[N << 1]; int tot, n, m; struct CanStill { int id[Blo + 10], s[Blo + 10]; void Init() { memset (id, 0, sizeof id); memset (s, 0, sizeof s); } void upd (int u, int y) { int p = (u - 1) / Blo + 1, x = u - (p - 1) * Blo; c[++tot] = c[id[p]]; c[tot].upd(x, y), id[p] = tot; For (i, 1, Blo) s[i] = (1ll * s[i - 1] * pw[Blo] + c[id[i]].h[Blo]) % Mod; } int ask (int u) { int p = (u - 1) / Blo + 1, x = u - (p - 1) * Blo; return (1ll * s[p - 1] * pw[x] + c[id[p]].h[x]) % Mod; } int get (int u) { if (u > n) return -1; int p = (u - 1) / Blo + 1, x = u - (p - 1) * Blo; return c[id[p]].v[x]; } } a[N]; int b[N]; int LCP (int x, int y) { if (x == y) return n - x + 1; if (x > y) swap(x, y); int l = 0, r = n - y + 1; while ( l < r ) { int mid = (l + r + 1) >> 1; if (a[x].ask(x + mid - 1) == a[y].ask(y + mid - 1)) l = mid; else r = mid - 1; } return l; } int sa[N]; int las[N]; bool cmp (int x, int y) { int w = LCP(x, y); return a[x].get(x + w) < a[y].get(y + w); }
signed main() { while ( ~scanf ("%lld", &n) ) { pw[0] = 1, tot = 0; ll Ans = 0; For (i, 1, n) { read(b[i]); pw[i] = 1ll * pw[i - 1] * Base % Mod; las[i] = 0; } a[n + 1].Init(); foR (i, n, 1) { Ans += i; a[i] = a[i + 1], sa[i] = i; if (las[b[i]]) a[i].upd(las[b[i]], las[b[i]] - i); las[b[i]] = i; } sort (sa + 1, sa + n + 1, cmp); For (i, 1, n - 1) Ans -= LCP(sa[i], sa[i + 1]); printf ("%lld\n", Ans); } }
|