Test instructions: Gives the sum of the values of all the different substrings that do not contain a leading 0 for the number of n strings
Idea: Splicing the numbers together, constructing the Sam, and then taking the length of each state Len as the eigenvalues from small to large sort, from go to post-processing each state, equivalent to the topological order on the graph to consolidate the calculation of the answer.
#include <bits/stdc++.h>using namespace std, #define X first#define Y second#define pb (x) push_back (x) #define MP (X, Y) Make_pair (x, y) #define ALL (a) (a). Begin (), (a). End () #define MSET (A, X) memset (A, X, sizeof (a)) #define MCPY (A, b) memcpy (A, B, sizeof (b)) #define CAS () int T, cas = 0; Cin >> T; while (T--) template<typename T>bool UMAX (t&a, const t&b) {return a<b? A=b,true): false;} Template<typename T>bool umin (t&a, const t&b) {return b<a? ( A=b,true): false;} typedef long Long Ll;typedef pair<int, int> pii; #ifndef online_judge #include "local.h" #endifconst int mod = 2012 ; const int N = 2e5;class SAM {public:void init () {memset (node, 0, sizeof (node)); Sz = last = 0; Node[0].len = 0; Node[0].link =-1; SZ + +; } void Add (char c) {int cur = sz + +; Node[cur].len = Node[last].len + 1; int p; for (p = last; ~p &&!node[p].next[c]; p = node[p].link) {node[P].next[c] = cur; } if (p = =-1) node[cur].link = 0; else {int q = node[p].next[c]; if (node[p].len + 1 = = Node[q].len) Node[cur].link = q; else {int clone = sz + +; Node[clone] = Node[q]; Node[clone].len = Node[p].len + 1; for (; ~p && node[p].next[c] = = q; p = node[p].link) {Node[p].next[c] = clone; } Node[q].link = Node[cur].link = Clone; }} last = cur; } int c[n << 1], p[n << 1]; int Getans () {mset (c, 0); for (int i = 0; i < sz; i + +) C[node[i].len] + +; for (int i = 1; I <= sz; i + +) C[i] + = c[i-1]; for (int i = 0; i < sz; i + +) p[--C[node[i].len]] = i; int ans = 0; node[0].cnt = 1; for (int i = 0; i < sz; i + +) {int cur = p[i]; for (int j = 0; J < J + +) {if (!cur &&!j | |!node[cur].next[j]) continue; int next = Node[cur].next[j]; Node[next].sum = (node[next].sum + node[cur].sum * + j * node[cur].cnt)% MoD; node[next].cnt = (node[next].cnt + node[cur].cnt)% MoD; } ans = (ans + node[cur].sum)% MoD; } return ans; }private:const static int SZ = 11; struct State {int Len, link; int Next[sz]; int sum, CNT; }; State node[n << 1]; int sz, last;}; SAM Sam;char S[123456];int Main () {#ifndef Online_judge freopen ("In.txt", "R", stdin); Freopen ("OUT.txt", "w", stdout); #endif//Online_judge int n; while (CIN >> N) {sam.init (); for (int i = 0; i < n; i + +) {scanf ("%s", s); for (int j = 0; s[j]; j + +) {Sam.add (s[j]-' 0 '); } sam.add (10); } cout << Sam.getans () << Endl; } return 0;}
[hdu4436 str2int] suffix automaton sam (or suffix array sa)