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 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
| #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<queue> using namespace std; typedef long long ll; #define MAXN 500006
int n , lst , m;
struct SAM{ int son[MAXN][27]; int par[MAXN] , len[MAXN]; int cnt; int sz[MAXN]; int head[MAXN] , to[MAXN << 1] , nex[MAXN << 1] , ecn; ll num;
void init( ) { memset( son , 0 , sizeof son ); memset( head , 0 , sizeof head ); cnt = lst = 1; ecn = 0; } void ade( int u , int v ) { nex[++ecn] = head[u] , head[u] = ecn , to[ecn] = v; } void addall( ) { for( int i = 2 ; i <= cnt ; ++ i ) ade( par[i] , i ); } void ins( int x ) { int cur = ++ cnt; len[cur] = len[lst] + 1 , sz[cur] = 1; int p = lst; while( p && !son[p][x] ) son[p][x] = cur , p = par[p]; if( !p ) par[cur] = 1; else { int q = son[p][x]; if( len[q] == len[p] + 1 ) par[cur] = q; else { int cl = ++ cnt; memcpy( son[cl] , son[q] , sizeof son[q] ); par[cl] = par[q]; len[cl] = len[p] + 1 , par[q] = par[cur] = cl; for( ; son[p][x] == q ; p = par[p] ) son[p][x] = cl; } } lst = cur; } int L[MAXN] , R[MAXN] , dfn; void dfs( int u ) { L[u] = ++ dfn; for( int i = head[u] ; i ; i = nex[i] ) dfs( to[i] ); R[u] = dfn; } int vis[MAXN]; int jump( int u ) { if( vis[u] ) return 0; vis[u] = 1; return len[u] - len[par[u]] + jump( par[u] ); }
int T[MAXN]; void add( int u , int c ) { while( u < MAXN ) T[u] += c , u += ( u & -u ); } int sum( int u ) { int ret = 0; while( u > 0 ) ret += T[u] , u -= ( u & -u ); return ret; }
void getit( int u ) {
num += jump( u ); add( L[u] , 1 ); }
int mach( char* c , int l ) { int cur = 1; for( int i = 0 ; i < l ; ++ i ) { if( !son[cur][c[i] - 'a'] ) return 0; else cur = son[cur][c[i] - 'a']; } return sum( R[cur] ) - sum( L[cur] - 1 ); } } S ;
int head[MAXN] , to[MAXN << 1] , nex[MAXN << 1] , wt[MAXN] , ecn; void ade( int u , int v , int w ) { to[++ ecn] = v , nex[ecn] = head[u] , head[u] = ecn , wt[ecn] = w; } int pos[MAXN] , fa[MAXN]; vector<int> ps[MAXN]; int cni; void bfs( int u ) { queue<int> Q; Q.push( u ); while( !Q.empty( ) ) { int x = Q.front(); Q.pop(); for( int i = head[x] ; i ; i = nex[i] ) { int v = to[i]; if( fa[x] == v || fa[v] ) continue; fa[v] = x; lst = pos[x]; S.ins( wt[i] ); pos[v] = lst , Q.push( v ); ps[cni].push_back( v ); } } }
char ch[MAXN]; int bk[MAXN] , ln[MAXN] , id , tot; char op[MAXN]; struct query { int opt , id; } Q[MAXN] ;
int main() { scanf("%*d"); cin >> n; for( int i = 1 , u , v ; i < n ; ++ i ) { scanf("%d%d%s",&u,&v,ch); ade( u , v , ch[0] - 'a' ) , ade( v , u , ch[0] - 'a' ); } S.init(); pos[1] = 1; bfs( 1 ); cin >> m; int opt , rt , s; for( int i = 1 ; i <= m ; ++ i ) { scanf("%d",&opt); if( opt == 1 ) { Q[i].opt = 1; } else if( opt == 2 ) { Q[i].opt = 2; ++ cni; scanf("%d%d",&rt,&s); for( int i = 1 , u , v ; i < s ; ++ i ) { scanf("%d%d%s",&u,&v,ch); ade( u , v , ch[0] - 'a' ) , ade( v , u , ch[0] - 'a' ); } bfs( rt ); Q[i].id = cni; } else { scanf("%s",op + tot); bk[i] = tot , ln[i] = strlen( op + tot ); tot += ln[i]; Q[i].opt = 3; } } Q[0].opt = 2; S.addall(); S.dfs( 1 );
for( int i = 0 ; i <= m ; ++ i ) { int o = Q[i].opt; if( o == 1 ) { printf("%lld\n",S.num); } else if( o == 2 ) { int c = Q[i].id; for( int j = 0 ; j < ps[c].size() ; ++ j ) { int u = ps[c][j]; S.getit( pos[u] ); } } else { printf("%d\n",S.mach( op + bk[i] , ln[i] )); } } }
|