Advertisement
ivnikkk

Untitled

Jan 25th, 2022
50
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.80 KB | None | 0 0
  1. #pragma GCC optimize("03")
  2. #define _CRT_SECURE_NO_WARNINGS
  3. #include "bits/stdc++.h"
  4. using namespace std;
  5. using namespace chrono;
  6. #define all(a) a.begin(), a.end()
  7. #define allr(a) a.rbegin(), a.rend()
  8. #define endl "\n"
  9. #define fast_io ios_base::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
  10. mt19937 rnd(std::chrono::high_resolution_clock::now().time_since_epoch().count());
  11. typedef long long ll;
  12. typedef long double ld;
  13.  
  14. static struct FastInput {
  15.     static constexpr int BUF_SIZE = 1 << 20;
  16.     char buf[BUF_SIZE];
  17.     size_t chars_read = 0;
  18.     size_t buf_pos = 0;
  19.     FILE* in = stdin;
  20.     char cur = 0;
  21.     inline char get_char() {
  22.         if (buf_pos >= chars_read) {
  23.             chars_read = fread(buf, 1, BUF_SIZE, in);
  24.             buf_pos = 0;
  25.             buf[0] = (chars_read == 0 ? -1 : buf[0]);
  26.         }
  27.         return cur = buf[buf_pos++];
  28.     }
  29.  
  30.     inline void tie(int) {}
  31.  
  32.     inline explicit operator bool() {
  33.         return cur != -1;
  34.     }
  35.  
  36.     inline static bool is_blank(char c) {
  37.         return c <= ' ';
  38.     }
  39.  
  40.     inline bool skip_blanks() {
  41.         while (is_blank(cur) && cur != -1) {
  42.             get_char();
  43.         }
  44.         return cur != -1;
  45.     }
  46.  
  47.     inline FastInput& operator>>(char& c) {
  48.         skip_blanks();
  49.         c = cur;
  50.         return *this;
  51.     }
  52.  
  53.     inline FastInput& operator>>(string& s) {
  54.         if (skip_blanks()) {
  55.             s.clear();
  56.             do {
  57.                 s += cur;
  58.             } while (!is_blank(get_char()));
  59.         }
  60.         return *this;
  61.     }
  62.  
  63.     template <typename T>
  64.     inline FastInput& read_integer(T& n) {
  65.         n = 0;
  66.         if (skip_blanks()) {
  67.             int sign = +1;
  68.             if (cur == '-') {
  69.                 sign = -1;
  70.                 get_char();
  71.             }
  72.             do {
  73.                 n += n + (n << 3) + cur - '0';
  74.             } while (!is_blank(get_char()));
  75.             n *= sign;
  76.         }
  77.         return *this;
  78.     }
  79.  
  80.     template <typename T>
  81.     inline typename enable_if<is_integral<T>::value, FastInput&>::type operator>>(T& n) {
  82.         return read_integer(n);
  83.     }
  84.  
  85. #if !defined(_WIN32) || defined(_WIN64)
  86.     inline FastInput& operator>>(__int128& n) {
  87.         return read_integer(n);
  88.     }
  89. #endif
  90.  
  91.     template <typename T>
  92.     inline typename enable_if<is_floating_point<T>::value, FastInput&>::type operator>>(T& n) {
  93.         // not sure if really fast, for compatibility only
  94.         n = 0;
  95.         if (skip_blanks()) {
  96.             string s;
  97.             (*this) >> s;
  98.             sscanf(s.c_str(), "%lf", &n);
  99.         }
  100.         return *this;
  101.     }
  102. } fast_input;
  103.  
  104. static struct FastOutput {
  105.     static constexpr int BUF_SIZE = 1 << 20;
  106.     char buf[BUF_SIZE];
  107.     size_t buf_pos = 0;
  108.     static constexpr int TMP_SIZE = 1 << 20;
  109.     char tmp[TMP_SIZE];
  110.     FILE* out = stdout;
  111.  
  112.     inline void put_char(char c) {
  113.         buf[buf_pos++] = c;
  114.         if (buf_pos == BUF_SIZE) {
  115.             fwrite(buf, 1, buf_pos, out);
  116.             buf_pos = 0;
  117.         }
  118.     }
  119.  
  120.     ~FastOutput() {
  121.         fwrite(buf, 1, buf_pos, out);
  122.     }
  123.  
  124.     inline FastOutput& operator<<(char c) {
  125.         put_char(c);
  126.         return *this;
  127.     }
  128.  
  129.     inline FastOutput& operator<<(const char* s) {
  130.         while (*s) {
  131.             put_char(*s++);
  132.         }
  133.         return *this;
  134.     }
  135.  
  136.     inline FastOutput& operator<<(const string& s) {
  137.         for (int i = 0; i < (int)s.size(); i++) {
  138.             put_char(s[i]);
  139.         }
  140.         return *this;
  141.     }
  142.  
  143.     template <typename T>
  144.     inline char* integer_to_string(T n) {
  145.         // beware of TMP_SIZE
  146.         char* p = tmp + TMP_SIZE - 1;
  147.         if (n == 0) {
  148.             *--p = '0';
  149.         }
  150.         else {
  151.             bool is_negative = false;
  152.             if (n < 0) {
  153.                 is_negative = true;
  154.                 n = -n;
  155.             }
  156.             while (n > 0) {
  157.                 *--p = (char)('0' + n % 10);
  158.                 n /= 10;
  159.             }
  160.             if (is_negative) {
  161.                 *--p = '-';
  162.             }
  163.         }
  164.         return p;
  165.     }
  166.  
  167.     template <typename T>
  168.     inline typename enable_if<is_integral<T>::value, char*>::type stringify(T n) {
  169.         return integer_to_string(n);
  170.     }
  171.  
  172. #if !defined(_WIN32) || defined(_WIN64)
  173.     inline char* stringify(__int128 n) {
  174.         return integer_to_string(n);
  175.     }
  176. #endif
  177.  
  178.     template <typename T>
  179.     inline typename enable_if<is_floating_point<T>::value, char*>::type stringify(T n) {
  180.         sprintf(tmp, "%.17f", n);
  181.         return tmp;
  182.     }
  183.  
  184.     template <typename T>
  185.     inline FastOutput& operator<<(const T& n) {
  186.         auto p = stringify(n);
  187.         for (; *p != 0; p++) {
  188.             put_char(*p);
  189.         }
  190.         return *this;
  191.     }
  192. } fast_output;
  193. #define cin fast_input
  194. #define cout fast_output
  195.  
  196.  
  197.  
  198.  
  199.  
  200. string p;
  201. struct Node {
  202.     ll go[26], cur = 0, terminal = 0, binup[21], dp = 0, prefix[27], siz = 0, down[26];
  203. };
  204.  
  205. vector<Node> trie(1);
  206. void add(string& s) {
  207.     ll cur_v = 0;
  208.     for (ll i = 0; i < (ll)s.size(); i++) {
  209.         char level = s[i] - 'a';
  210.         if (trie[cur_v].go[level] == 0) {
  211.             trie.push_back(Node());
  212.             trie[cur_v].go[level] = (ll)trie.size() - 1;
  213.             trie[trie[cur_v].go[level]].cur = trie[cur_v].cur + 1;
  214.         }
  215.         cur_v = trie[cur_v].go[level];
  216.     }
  217.     trie[cur_v].terminal++;
  218.     return;
  219. }
  220. void dfs(ll v = 0, ll p = 0) {
  221.     trie[v].binup[0] = p;
  222.     for (ll i = 0; i + 1 < 21; i++)
  223.         trie[v].binup[i + 1] = trie[trie[v].binup[i]].binup[i];\
  224.     trie[v].dp += trie[p].dp + trie[v].terminal;
  225.     trie[v].siz = trie[v].terminal;
  226.     ll now_sum = 0;
  227.     trie[v].prefix[0] = 0;
  228.     for (ll c = 0; c < 26; c++) {
  229.         if (trie[v].go[c] != 0) {
  230.             trie[trie[v].go[c]].dp += now_sum;
  231.             dfs(trie[v].go[c], v);
  232.             trie[v].siz += trie[trie[v].go[c]].siz;
  233.             trie[v].down[c] = trie[trie[v].go[c]].down[c];
  234.             now_sum += trie[trie[v].go[c]].siz;
  235.         }
  236.         else {
  237.             trie[v].down[c] = v;
  238.         }
  239.         trie[v].prefix[c + 1] = now_sum;
  240.     }
  241. }
  242.  
  243. ll cur_v = 0, lvl = -1;
  244. ll get() {
  245.     ll ans = trie[cur_v].dp;
  246.     if ((ll)p.size() == trie[cur_v].cur) {
  247.         ans -= trie[cur_v].terminal;
  248.     }
  249.     else {
  250.         for (ll i = 0; i < lvl; i++) {
  251.             if (trie[cur_v].go[i] != 0) {
  252.                 ans += trie[trie[cur_v].go[i]].siz;
  253.             }
  254.         }
  255.     }
  256.     return ans;
  257. }
  258. void need(ll c) {
  259.      cur_v = trie[cur_v].down[c];
  260.     ll to = max(trie[cur_v].cur-(ll)p.size(), (ll)0);
  261.     for (ll i = 20; i >= 0; --i) {
  262.         if (to >> i & 1) {
  263.             cur_v = trie[cur_v].binup[i];
  264.         }
  265.     }
  266.     if (trie[cur_v].cur == (ll)p.size())
  267.         lvl = -1;
  268.     else
  269.         lvl = c;
  270. }
  271. signed main() {
  272. #ifdef _DEBUG
  273.     freopen("input.txt", "r", stdin);
  274.     freopen("output.txt", "w", stdout);
  275. #endif
  276.     srand(time(NULL));
  277.     ll n;
  278.     cin >> n;
  279.     ll q;
  280.     cin >> q;
  281.     cin >> p;
  282.     for (ll i = 0; i < n; i++) {
  283.         string s;
  284.         cin >> s;
  285.         add(s);
  286.     }
  287.     dfs();
  288.     for (ll i = 0; i < (ll)p.size(); i++) {
  289.         ll level = p[i] - 'a';
  290.         if (trie[cur_v].go[level] == 0) {
  291.             lvl = level;
  292.             break;
  293.         }
  294.         cur_v = trie[cur_v].go[level];
  295.     }
  296.     cout << get() << endl;
  297.     while (q--) {
  298.         ll pos;
  299.         char in;
  300.         cin >> pos >> in;
  301.         --pos;
  302.         ll c = in - 'a';
  303.         if (pos > trie[cur_v].cur) {
  304.         }
  305.         else {
  306.             ll to = trie[cur_v].cur - pos;
  307.             for (ll i = 20; i >= 0; --i) {
  308.                 if (to >> i & 1) {
  309.                     cur_v = trie[cur_v].binup[i];
  310.                 }
  311.             }
  312.             need(c);
  313.         }
  314.         cout << get() << endl;;
  315.     }
  316.  
  317. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement