Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #define ll long long
- using namespace std;
- struct node {
- map<char, int> to;
- int slink = -1;
- int link = -1;
- vector<int> term;
- char pc = '$';
- int p = -1;
- ll to_add = 0;
- node(){}
- };
- const int max_sz = 1000050;
- node trie[max_sz];
- int sz = 1;
- void add(string& s, int id) {
- int cur = 0;
- for (int i = 0; i < s.length(); i++) {
- if (!trie[cur].to.count(s[i])) {
- trie[sz].p = cur;
- trie[sz].pc = s[i];
- trie[cur].to[s[i]] = sz++;
- }
- cur = trie[cur].to[s[i]];
- }
- trie[cur].term.push_back(id);
- }
- int go(int v, char c);
- int go_link(int v) {
- if (trie[v].link == -1) {
- if (v == 0 || trie[v].p == 0) {
- trie[v].link = 0;
- } else {
- trie[v].link = go(go_link(trie[v].p), trie[v].pc);
- }
- }
- return trie[v].link;
- }
- int go_slink(int v) {
- if (trie[v].slink == -1) {
- if (trie[go_link(v)].term.size() != 0 || v == 0) {
- trie[v].slink = go_link(v);
- } else {
- trie[v].slink = go_slink(go_link(v));
- }
- }
- return trie[v].slink;
- }
- int go(int v, char c) {
- if (!trie[v].to.count(c)) {
- if (v == 0) {
- trie[v].to[c] = 0;
- } else {
- trie[v].to[c] = go(go_link(v), c);
- }
- }
- return trie[v].to[c];
- }
- vector<vector<pair<int, char>>> g;
- vector<int> dp;
- vector<ll> occur;
- void dfs(int v, int p, int state) {
- int cur = state;
- while (cur != 0) {
- if (trie[cur].term.size() != 0) {
- trie[cur].to_add += dp[v];
- }
- cur = go_slink(cur);
- }
- for (pair<int, char>& to : g[v]) {
- if (to.first == p) continue;
- dfs(to.first, v, go(state, to.second));
- }
- }
- int dfs_dp(int v, int p) {
- for (pair<int, char>& to : g[v]) {
- dp[v] += dfs_dp(to.first, v);
- }
- return dp[v];
- }
- int main()
- {
- ios_base::sync_with_stdio(false);
- cin.tie(0);
- cout.tie(0);
- int n;
- cin >> n;
- g.assign(n + 1, vector<pair<int, char>>());
- dp.assign(n + 1, 0);
- int p, term;
- string pc;
- for (int i = 0; i < n; i++) {
- cin >> p >> pc >> term;
- g[p].push_back({i + 1, pc[0]});
- dp[i + 1] = term;
- }
- dfs_dp(0, -1);
- cin >> n;
- occur.assign(n, 0);
- string s;
- for (int i = 0; i < n; i++) {
- cin >> s;
- add(s, i);
- }
- dfs(0, -1, 0);
- for (int i = 0; i < sz; i++) {
- for (int j : trie[i].term) {
- occur[j] += trie[i].to_add;
- }
- }
- for (int i = 0; i < n; i++) {
- cout << occur[i] << '\n';
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement