Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma GCC optimize("03")
- #define _CRT_SECURE_NO_WARNINGS
- #include "bits/stdc++.h"
- using namespace std;
- using namespace chrono;
- #define all(a) a.begin(), a.end()
- #define allr(a) a.rbegin(), a.rend()
- #define endl "\n"
- #define fast_io ios_base::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
- mt19937 rnd(std::chrono::high_resolution_clock::now().time_since_epoch().count());
- typedef long long ll;
- typedef long double ld;
- string p;
- struct Node {
- ll go[26], cur = 0, terminal = 0, binup[21], dp = 0, siz = 0, down[26];
- };
- vector<Node> trie(1);
- void add(string& s) {
- ll cur_v = 0;
- for (ll i = 0; i < (ll)s.size(); i++) {
- char level = s[i] - 'a';
- if (trie[cur_v].go[level] == 0) {
- trie.push_back(Node());
- trie[cur_v].go[level] = (ll)trie.size() - 1;
- trie[trie[cur_v].go[level]].cur = trie[cur_v].cur + 1;
- }
- cur_v = trie[cur_v].go[level];
- }
- trie[cur_v].terminal++;
- return;
- }
- void dfs(ll v = 0, ll p = 0) {
- trie[v].binup[0] = p;
- for (ll i = 0; i + 1 < 21; i++)
- trie[v].binup[i + 1] = trie[trie[v].binup[i]].binup[i];\
- trie[v].dp += trie[p].dp + trie[v].terminal;
- trie[v].siz = trie[v].terminal;
- ll now_sum = 0;
- for (ll c = 0; c < 26; c++) {
- if (trie[v].go[c] != 0) {
- trie[trie[v].go[c]].dp += now_sum;
- dfs(trie[v].go[c], v);
- trie[v].siz += trie[trie[v].go[c]].siz;
- trie[v].down[c] = trie[trie[v].go[c]].down[c];
- now_sum += trie[trie[v].go[c]].siz;
- }
- else {
- trie[v].down[c] = v;
- }
- }
- }
- ll cur_v = 0, lvl = -1;
- ll get() {
- ll ans = trie[cur_v].dp;
- if ((ll)p.size() == trie[cur_v].cur) {
- ans -= trie[cur_v].terminal;
- }
- else {
- for (ll i = 0; i < lvl; i++) {
- if (trie[cur_v].go[i] != 0) {
- ans += trie[trie[cur_v].go[i]].siz;
- }
- }
- }
- return ans;
- }
- void need(ll c) {
- cur_v = trie[cur_v].down[c];
- ll to = max(trie[cur_v].cur-(ll)p.size(), (ll)0);
- for (ll i = 20; i >= 0; --i) {
- if (to >> i & 1) {
- cur_v = trie[cur_v].binup[i];
- }
- }
- if (trie[cur_v].cur == (ll)p.size())
- lvl = -1;
- else
- lvl = c;
- }
- signed main() {
- #ifdef _DEBUG
- freopen("input.txt", "r", stdin);
- freopen("output.txt", "w", stdout);
- #endif
- srand(time(NULL));
- fast_io;
- ll n;
- cin >> n;
- ll q;
- cin >> q;
- cin >> p;
- for (ll i = 0; i < n; i++) {
- string s;
- cin >> s;
- add(s);
- }
- dfs();
- for (ll i = 0; i < (ll)p.size(); i++) {
- ll level = p[i] - 'a';
- if (trie[cur_v].go[level] == 0) {
- lvl = level;
- break;
- }
- cur_v = trie[cur_v].go[level];
- }
- cout << get() << endl;
- while (q--) {
- ll pos;
- char in;
- cin >> pos >> in;
- --pos;
- ll c = in - 'a';
- if (pos > trie[cur_v].cur) {
- }
- else {
- ll to = trie[cur_v].cur - pos;
- for (ll i = 20; i >= 0; --i) {
- if (to >> i & 1) {
- cur_v = trie[cur_v].binup[i];
- }
- }
- need(c);
- }
- cout << get() << endl;;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment