Because Bzoj "data files are too large, only the first three sets of data tests are available." So I wrote in the examination room 60 points of the point of treatment handed up also a.
My point of division of the time Complexity is $o (TNMLOGN) $, listening to the solution did not understand the $o (TNLOGN) $, and I heard that the mark to use the string hash, however, I do not, so first leave a pit, paste their own 60 points code, out of the way I learned to hash and then do
#include <cstdio> #include <cstring> #include <algorithm>using namespace std;const int N = 1000003;void Read (int &k) {k = 0; int fh = 1; char c = GetChar (); for (; c < ' 0 ' | | c > ' 9 '; c = GetChar ()) if (c = = '-') FH =- 1;for (; c >= ' 0 ' && C <= ' 9 '; c = GetChar ()) K = (k << 1) + (k << 3) + C-' 0 '; k = k * FH;} struct Node {int nxt, to;} E[n << 1];int N, M, CNT, point[n], root, Qu[n], fa[n], t[n], Sz[n];char c[n], Mu[n];bool vis[n], bo[n];void ins (int x, int y) {e[++cnt].nxt = point[x]; e[cnt].to = y; POINT[X] = cnt;} void findrt (int x) {int p = 0, u, q = 1; qu[1] = x; fa[x] = 0;while (P! = q) {u = qu[++p]; Bo[u] = 1; Sz[u] = 1;for (int TM p = Point[u]; tmp TMP = E[TMP].NXT) if (!vis[e[tmp].to] && e[tmp].to! = Fa[u]) qu[++q] = e[tmp].to, fa[e[tmp].to] = u;} for (int i = q; I >= 1; i) {u = qu[i];if (Bo[u] && sz[u] * 2 > Q) {root = U; return;} Sz[fa[u]] + = SZ[U];IF (sz[u] * 2 > Q) bo[fa[u]] = 0;}} int Leftnow, RightNow, LEftsum, Rightsum, ret;void bfsleft (int x) {int p = 0, u, q = 1, tt; QU[1] = X;while (P! = q) {u = qu[++p];for (int tmp = PO Int[u]; tmp TMP = E[TMP].NXT) if (!vis[e[tmp].to] && e[tmp].to! = Fa[u] && c[e[tmp].to] = = Mu[tt = ((T[u]-1 + m)% m) ]) Fa[e[tmp].to] = u, t[e[tmp].to] = TT, qu[++q] = e[tmp].to;} for (int i = 1; I <= Q; ++i) if (t[qu[i]] = = 0) ++leftnow;} void bfsright (int x) {int p = 0, u, q = 1, tt; QU[1] = X;while (P! = q) {u = qu[++p];for (int tmp = point[u]; tmp; TMP = e[ TMP].NXT) if (!vis[e[tmp].to] && e[tmp].to! = Fa[u] && c[e[tmp].to] = = Mu[tt = ((T[u] + 1)% m)]) fa[e[tmp]. to] = u, t[e[tmp].to] = TT, qu[++q] = e[tmp].to;} for (int i = 1; I <= Q; ++i) if (t[qu[i]] = = (m-1)) ++rightnow;} void work (int. x) {Vis[x] = 1;int tt;for (int to = 0, to < m, ++to) if (c[x] = = Mu[to]) {leftsum = 0; rightsum = 0; if (to = = 0) leftsum = 1; if (to = = m-1) Rightsum = 1;for (int i = point[x]; i; i = e[i].nxt) if (!vis[e[i].to]) {Leftnow = 0;if (c[e[i].to] = = Mu[TT = (to-1 + m)% m]) Fa[e[i].to] = x, t[e[i].to] = TT, Bfsleft (e[i].to); rightnow = 0;if (c[e[i].to] = = Mu[tt = (to + 1)% m]) fa[e[i].to] = x, t [E[i].to] = TT, Bfsright (e[i].to), ret + = Leftsum * Rightnow;ret + = Rightsum * Leftnow;leftsum + = Leftnow; Rightsum + = Rightnow;leftnow = 0; RightNow = 0;}} for (int i = point[x]; I, i = e[i].nxt) if (!vis[e[i].to]) {FINDRT (e[i].to); work (root);}} int main () {freopen ("pattern.in", "R", stdin), Freopen ("Pattern.out", "w", stdout), int T, u, v;read (t), while (t--) {Read (n ); Read (m); scanf ("%s", C + 1); cnt = 0; memset (point, 0, sizeof); memset (Vis, 0, sizeof (VIS)), for (int i = 1; i < n; ++i) {Read (u); Read (v); Ins (U, v); Ins (v, u); scanf ("%s", mu), ret = 0;FINDRT (1), Work (root);p rintf ("%d\n", ret);} return 0;}
"Bzoj 4598" "Sdoi Round2 Day1 T3" pattern string