Dang_Quan_10_Tin

VIRUS

Jan 28th, 2021
281
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.14 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <queue>
  4. #include <cmath>
  5. #define task "VIRUS"
  6. using namespace std;
  7. using ll = long long;
  8. using ld = long double;
  9.  
  10. const int N = 1e5 + 5;
  11. struct node
  12. {
  13.     node *p, *par, *child[2];
  14.     int sum, val, en;
  15.     node(const int &v = 0)
  16.     {
  17.         p = par = this;
  18.         sum = en = 0;
  19.         val = v;
  20.         child[0] = child[1] = NULL;
  21.     }
  22. };
  23. struct Trie
  24. {
  25.     node root;
  26.     string s;
  27.     void Add(const string &s, const int &v)
  28.     {
  29.         node *a = &root;
  30.         int id = 0;
  31.         while (1)
  32.         {
  33.             if (id == (int)s.size())
  34.             {
  35.                 a->en += v;
  36.                 a->sum += v;
  37.                 return;
  38.             }
  39.             if (!(a->child[s[id] - '0']))
  40.             {
  41.                 a->child[s[id] - '0'] = new node;
  42.                 a->child[s[id] - '0']->par = a;
  43.                 a->child[s[id] - '0']->val = s[id] - '0';
  44.             }
  45.             a = a->child[s[id] - '0'];
  46.             ++id;
  47.         }
  48.     }
  49.     ll Cal(const string &s)
  50.     {
  51.         ll ans(0);
  52.         int id = 0;
  53.         node *a = &root;
  54.         while (1)
  55.         {
  56.             if (id == (int)s.size())
  57.                 break;
  58.             while (a != (&root) && (!(a->child[s[id] - '0'])))
  59.                 a = a->p;
  60.             if (a->child[s[id] - '0'])
  61.             {
  62.                 ans += a->child[s[id] - '0']->sum;
  63.                 a = a->child[s[id] - '0'];
  64.             }
  65.             ++id;
  66.         }
  67.         return ans;
  68.     }
  69.     void Prepare()
  70.     {
  71.         queue<node *> ss;
  72.         if (root.child[0])
  73.             ss.emplace(root.child[0]);
  74.         if (root.child[1])
  75.             ss.emplace(root.child[1]);
  76.         while (ss.size())
  77.         {
  78.             auto c = ss.front();
  79.             ss.pop();
  80.             auto k = c->par->p;
  81.             if (c->par != (&root))
  82.             {
  83.                 while (k != (&root) && (!(k->child[c->val])))
  84.                     k = k->p;
  85.                 if (k->child[c->val])
  86.                 {
  87.                     c->p = k->child[c->val];
  88.                     c->sum += c->p->sum;
  89.                 }
  90.                 else
  91.                     c->p = &root;
  92.             }
  93.             else
  94.                 c->p = &root;
  95.             if (c->child[0])
  96.                 ss.emplace(c->child[0]);
  97.             if (c->child[1])
  98.                 ss.emplace(c->child[1]);
  99.         }
  100.     }
  101.     void clear(node *a)
  102.     {
  103.         if (a->child[0])
  104.         {
  105.             clear(a->child[0]);
  106.             delete a->child[0];
  107.         }
  108.         if (a->child[1])
  109.         {
  110.             clear(a->child[1]);
  111.             delete a->child[1];
  112.         }
  113.         a->child[0] = a->child[1] = NULL;
  114.         a->p = a->par = a;
  115.         a->sum = a->en = 0;
  116.     }
  117.     void Clear()
  118.     {
  119.         clear(&root);
  120.     }
  121.     void dfs(node *a, Trie &f)
  122.     {
  123.         if (a->en != 0)
  124.             f.Add(s, a->en);
  125.         if (a->child[0])
  126.         {
  127.             s.push_back('0');
  128.             dfs(a->child[0], f);
  129.             s.pop_back();
  130.         }
  131.         if (a->child[1])
  132.         {
  133.             s.push_back('1');
  134.             dfs(a->child[1], f);
  135.             s.pop_back();
  136.         }
  137.     }
  138.     void Copy(Trie &f)
  139.     {
  140.         s.clear();
  141.         dfs(&root, f);
  142.     }
  143. } f[20];
  144.  
  145. int q, now(0);
  146. bool ok;
  147.  
  148. void Read()
  149. {
  150.     cin >> q;
  151.     while (q--)
  152.     {
  153.         int x;
  154.         string s;
  155.         cin >> x >> s;
  156.         if (x == 0)
  157.         {
  158.             ++now;
  159.             int i = log2(now & -now);
  160.             for (int j = 0; j < i; ++j)
  161.             {
  162.                 f[j].Copy(f[i]);
  163.                 f[j].Clear();
  164.             }
  165.             f[i].Add(s, 1);
  166.             f[i].Prepare();
  167.         }
  168.         else
  169.         {
  170.             ll ans(0);
  171.             for (int i = 0; i < 20; ++i)
  172.                 ans += f[i].Cal(s);
  173.             cout << ans << "\n";
  174.         }
  175.     }
  176. }
  177.  
  178. int32_t main()
  179. {
  180.     ios_base::sync_with_stdio(false);
  181.     cin.tie(nullptr);
  182.     if (fopen(task ".INP", "r"))
  183.     {
  184.         freopen(task ".INP", "r", stdin);
  185.         freopen(task ".OUT", "w", stdout);
  186.     }
  187.     Read();
  188.     //Solve();
  189. }
  190.  
Advertisement
Add Comment
Please, Sign In to add comment