得存一波板子了。。。。

先是广义后缀自动机的吧!

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #define rep(i,j,k) for(register int i = j; i <= k; i++)
 6 #define dow(i,j,k) for(register int i = j; i >= k; i--)
 7 #define ll long long
 8 using namespace std; 
 9 
10 inline int read() {
11     int s = 0, t = 1; char c = getchar();
12     while( !isdigit(c) ) { if( c == '-' ) t = -1; c = getchar(); }
13     while( isdigit(c) ) s = s * 10 + c - 48, c = getchar();
14     return s * t;
15 }
16 
17 const int N = 1e5+5, M = 4000200;
18 int v, nv, p, du[N], fa[M], dep[M], son[M][10], tot = 1;
19 struct edge{ int to; edge*nxt; } e[N<<1], *pt = e, *head[N];
20 inline void add(int x,int y) {
21     du[x]++, du[y]++;
22     pt->to = y, pt->nxt = head[x], head[x] = pt++;
23     pt->to = x, pt->nxt = head[y], head[y] = pt++;
24 }
25 
26 inline int extend(int u,int t) {
27     if( v = son[u][t] ) {
28         if( dep[v] == dep[u] + 1 ) return v;
29         nv = ++tot, dep[nv] = dep[u] + 1;
30         fa[nv] = fa[v], fa[v] = nv;
31         memcpy(son[nv],son[v],sizeof(son[v]));
32         while( son[u][t] == v ) son[u][t] = nv, u = fa[u];
33         return nv;
34     }
35     p = ++tot, dep[p] = dep[u] + 1;
36     while( u && !son[u][t] ) son[u][t] = p, u = fa[u];
37     if( !u ) fa[p] = 1;
38     else { 
39         if( dep[v = son[u][t]] == dep[u] + 1 ) fa[p] = v;
40         else {
41             nv = ++tot, dep[nv] = dep[u] + 1;
42             fa[nv] = fa[v], fa[v] = fa[p] = nv;
43             memcpy(son[nv],son[v],sizeof(son[v]));
44             while( son[u][t] == v ) son[u][t] = nv, u = fa[u];
45         }
46     }
47     return p;
48 } 
49 
50 #define ez(i,j) for(edge*i = head[j]; i; i=i->nxt)
51 #define to i->to
52 int c[N];
53 inline void dfs(int x,int f,int now) {
54     now = extend(now,c[x]);
55     ez(i,x) if( to != f ) dfs(to,x,now);
56 }
57 
58 int main() {
59 //    freopen("in.txt","r",stdin);
60     int n = read(), m = read(); ll ans = 0;
61     rep(i,1,n) c[i] = read();
62     rep(i,1,n-1) add(read(),read());
63     rep(i,1,n) if( du[i] == 1 ) dfs(i,0,1);
64     rep(i,1,tot) ans += dep[i] - dep[fa[i]];
65     cout<<ans<<endl;
66     return 0;
67 }
View Code

 

人一我十,人十我万!追逐青春的梦想,怀着自信的心,永不放弃!仿佛已看到希望,尽管还在远方

posted on 2017-02-16 13:08  83131  阅读(122)  评论(0编辑  收藏  举报

导航