Advertisement
GuilhermeCpp

914-F

Mar 19th, 2025
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.53 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #define N 100010
  5. #define M 400010
  6. #define B 316
  7. #define base 1009
  8. #define mod 1000000009
  9. #define fi first
  10. #define se second
  11. #define pb push_back
  12. #define endl '\n'
  13.  
  14. typedef long long int ll;
  15.  
  16. struct NODE
  17. {
  18.  
  19.     int sum, lef, rig;
  20.  
  21. };
  22.  
  23. int n, q;
  24. string s, t;
  25.  
  26. string str;
  27. int tam;
  28.  
  29. int SA[N];
  30. int tempSA[N];
  31.  
  32. int RA[N];
  33. int tempRA[N];
  34.  
  35. int accu[N];
  36.  
  37. int ant[N];
  38. int LCP[N];
  39. int tempLCP[N];
  40. int where[N];
  41.  
  42. int pot[N];
  43.  
  44. int root[N];
  45. vector< NODE > st;
  46.  
  47. pair< ll, int > sts[M];
  48. pair< ll, int > stt[M];
  49.  
  50. vector< pair< int, int > > update;
  51.  
  52. void Init()
  53. {
  54.  
  55.     pot[0] = 1;
  56.    
  57.     for(int i = 1;i < N;i++)
  58.         pot[i] = (base * pot[i-1]) % mod;
  59.  
  60.     return;
  61.  
  62. }
  63.  
  64. void CS(int k)
  65. {
  66.  
  67.     int sum = 0, temp, i;
  68.    
  69.     memset(accu, 0, sizeof accu);
  70.    
  71.     for(i = 0;i < tam;i++)
  72.     {
  73.    
  74.         if(i + k < tam) accu[RA[i + k]]++;
  75.         else            accu[0]++;
  76.        
  77.     }
  78.    
  79.     for(i = 0;i < N;i++)
  80.     {
  81.    
  82.         temp = accu[i];
  83.         accu[i] = sum;
  84.         sum += temp;
  85.    
  86.     }
  87.    
  88.     for(i = 0;i < tam;i++)
  89.     {
  90.    
  91.         if((SA[i]+k)<tam)   tempSA[accu[RA[SA[i]+k]]++]=SA[i];
  92.         else                tempSA[accu[0]++] = SA[i];
  93.        
  94.     }
  95.    
  96.     for(i = 0;i < tam;i++) SA[i] = tempSA[i];
  97.    
  98.     return;
  99.  
  100. }
  101.  
  102. void buildSA(string &s)
  103. {
  104.  
  105.     s.pb('$');
  106.     tam = (int)(s.size());
  107.  
  108.     int cur, i, k;
  109.  
  110.     for(i = 0;i < tam;i++) SA[i] = i;
  111.     for(i = 0;i < tam;i++) RA[i] = (int)(s[i]);
  112.    
  113.     for(k = 1;k < tam;k <<= 1)
  114.     {
  115.    
  116.         CS(k);
  117.         CS(0);
  118.        
  119.         cur = 0;
  120.        
  121.         tempRA[SA[0]] = cur;
  122.        
  123.         for(i = 1;i < tam;i++)
  124.         {
  125.        
  126.             cur++;
  127.             if(RA[SA[i]] == RA[SA[i - 1]] && RA[SA[i] + k] == RA[SA[i - 1] + k]) cur--;
  128.             tempRA[SA[i]] = cur;
  129.        
  130.         }
  131.        
  132.         for(i = 0;i < tam;i++) RA[i] = tempRA[i];
  133.            
  134.     }
  135.    
  136.     ant[SA[0]] = -1;
  137.     for(i = 1;i < tam;i++) ant[SA[i]] = SA[i - 1];
  138.    
  139.     cur = 0;
  140.    
  141.     for(i = 0;i < tam;i++)
  142.     {
  143.    
  144.         if(ant[i] == -1)
  145.         {
  146.            
  147.             tempLCP[i] = 0;
  148.             continue;
  149.        
  150.         }
  151.    
  152.         while(s[i + cur] == s[ant[i] + cur]) cur++;
  153.        
  154.         tempLCP[i] = cur;
  155.         cur = max(cur - 1, 0);
  156.    
  157.     }
  158.    
  159.     for(i = 0;i < tam;i++) LCP[i] = tempLCP[SA[i]];    
  160.     for(i = 0;i < tam;i++) where[SA[i]] = i;
  161.    
  162.     return;
  163.  
  164. }
  165.  
  166. int Build(int l, int r)
  167. {
  168.  
  169.     int idx = (int)(st.size());
  170.     st.pb({0, -1, -1});
  171.  
  172.     if(l == r) return idx;
  173.  
  174.     int mid = ((l + r) >> 1);
  175.  
  176.     int a = Build(l, mid);
  177.     int b = Build(mid+1, r);
  178.  
  179.     st[idx].lef = a;
  180.     st[idx].rig = b;
  181.  
  182.     st[idx].sum = st[st[idx].lef].sum + st[st[idx].rig].sum;
  183.    
  184.     return idx;
  185.  
  186. }
  187.  
  188. int Update(int idx, int l, int r, int pos, int val)
  189. {
  190.  
  191.     int newIdx = (int)(st.size());
  192.     st.pb(st[idx]);
  193.  
  194.     if(l == r)
  195.     {
  196.  
  197.         st[newIdx].sum += val;
  198.         return newIdx;
  199.  
  200.     }
  201.    
  202.     int mid = ((l + r) >> 1);
  203.  
  204.     int p;
  205.  
  206.     if(pos <= mid)  p = Update(st[idx].lef, l, mid, pos, val);
  207.     else            p = Update(st[idx].rig, mid+1, r, pos, val);
  208.    
  209.     if(pos <= mid)  st[newIdx].lef = p;
  210.     else            st[newIdx].rig = p;
  211.  
  212.     st[newIdx].sum = st[st[newIdx].lef].sum + st[st[newIdx].rig].sum;
  213.    
  214.     return newIdx;
  215.  
  216. }
  217.  
  218. int Query(int idx, int l, int r, int a, int b)
  219. {
  220.  
  221.     if(r < a || b < l) return 0;
  222.  
  223.     if(a <= l && r <= b) return st[idx].sum;
  224.  
  225.     int mid = ((l + r) >> 1);
  226.  
  227.     return Query(st[idx].lef, l, mid, a, b) + Query(st[idx].rig, mid+1, r, a, b);
  228.  
  229. }
  230.  
  231. int Query(int a, int b, int l, int r)
  232. {
  233.    
  234.     if(r < l) return 0;
  235.     if(b < a) return 0;
  236.  
  237.     return Query(root[b], 0, n, l, r) - Query(root[a-1], 0, n, l, r);
  238.  
  239. }
  240.  
  241. void buildST()
  242. {
  243.  
  244.     root[0] = Build(0, n);
  245.     root[0] = Update(root[0], 0, n, where[0], 1);
  246.  
  247.     for(int i = 1;i <= n;i++) root[i] = Update(root[i-1], 0, n, where[i], 1);
  248.  
  249.     return;
  250.  
  251. }
  252.  
  253. void updateAll()
  254. {
  255.  
  256.     s = t;
  257.     buildSA(s);
  258.  
  259.     st.clear();
  260.     buildST();
  261.    
  262.     for(int i = 0;i < M;i++) sts[i] = stt[i];
  263.  
  264.     update.clear();
  265.  
  266.     return;
  267.  
  268. }
  269.  
  270. pair< int, int > getRange(string &p)
  271. {
  272.  
  273.     int a, b, na, nb, l, r, m, i;
  274.  
  275.     a = 0;
  276.     b = n;
  277.  
  278.     for(i = 0;i < (int)(p.size());i++)
  279.     {
  280.  
  281.         l = a;
  282.         r = b;
  283.         na = b+1;
  284.  
  285.         while(l <= r)
  286.         {
  287.  
  288.             m = ((l + r) >> 1);
  289.  
  290.             if(s[SA[m]+i] < p[i])
  291.             {
  292.  
  293.                 l = m + 1;
  294.  
  295.             }else
  296.             {
  297.  
  298.                 na = m;
  299.                 r = m - 1;
  300.  
  301.             }
  302.  
  303.         }
  304.  
  305.         l = a;
  306.         r = b;
  307.         nb = a-1;
  308.  
  309.         while(l <= r)
  310.         {
  311.  
  312.             m = ((l + r) >> 1);
  313.  
  314.             if(s[SA[m]+i] <= p[i])
  315.             {
  316.  
  317.                 nb = m;
  318.                 l = m + 1;
  319.  
  320.             }else
  321.             {
  322.  
  323.                 r = m - 1;
  324.  
  325.             }
  326.  
  327.         }
  328.  
  329.         a = na;
  330.         b = nb;
  331.  
  332.         if(b < a) break;
  333.  
  334.     }
  335.  
  336.     return {a, b};
  337.  
  338. }
  339.  
  340. pair< ll, int > mergeHash(pair< ll, int > a, pair< ll, int > b)
  341. {
  342.  
  343.     pair< ll, int > c;
  344.  
  345.     c.fi = (a.fi * pot[b.se] + b.fi) % mod;
  346.     c.se = a.se + b.se;
  347.  
  348.     return c;
  349.  
  350. }
  351.  
  352. void buildHash(pair< ll, int > st[], int idx, int l, int r)
  353. {
  354.  
  355.     if(l == r)
  356.     {
  357.  
  358.         st[idx] = {(int)(t[l]), 1};
  359.         return;
  360.  
  361.     }
  362.  
  363.     int nxt = (idx << 1);
  364.     int mid = ((l + r) >> 1);
  365.  
  366.     buildHash(st, nxt, l, mid);
  367.     buildHash(st, nxt+1, mid+1, r);
  368.  
  369.     st[idx] = mergeHash(st[nxt], st[nxt+1]);
  370.  
  371.     return;
  372.  
  373. }
  374.  
  375. void updateHash(pair< ll, int > st[], int idx, int l, int r, int pos)
  376. {
  377.  
  378.     if(l == r)
  379.     {
  380.  
  381.         st[idx] = {(int)(t[l]), 1};
  382.         return;
  383.  
  384.     }
  385.  
  386.     int nxt = (idx << 1);
  387.     int mid = ((l + r) >> 1);
  388.  
  389.     if(pos <= mid)  updateHash(st, nxt, l, mid, pos);
  390.     else            updateHash(st, nxt+1, mid+1, r, pos);
  391.  
  392.     st[idx] = mergeHash(st[nxt], st[nxt+1]);
  393.  
  394.     return;
  395.  
  396. }
  397.  
  398. pair< ll, int > queryHash(pair< ll, int > st[], int idx, int l, int r, int a, int b)
  399. {
  400.  
  401.     if(r < a || b < l) return {0LL, 0LL};
  402.  
  403.     if(a <= l && r <= b) return st[idx];
  404.  
  405.     int nxt = (idx << 1);
  406.     int mid = ((l + r) >> 1);
  407.  
  408.     return mergeHash(queryHash(st, nxt, l, mid, a, b), queryHash(st, nxt+1, mid+1, r, a, b));
  409.  
  410. }
  411.  
  412. int Solv(int l, int r, string &p)
  413. {
  414.  
  415.     int ans = 0, hp, a, b, t, i;
  416.  
  417.     pair< int, int > aux;
  418.  
  419.     set< int > positions;
  420.  
  421.     t = (int)(p.size());
  422.    
  423.     aux = getRange(p);
  424.     a = aux.fi;
  425.     b = aux.se;
  426.  
  427.     ans = Query(l, r-t+1, a, b);
  428.  
  429.     hp = 0;
  430.    
  431.     for(i = 0;i < t;i++)
  432.         hp = (base * hp + (int)(p[i])) % mod;
  433.        
  434.     for(auto [pos, ch] : update)
  435.     {
  436.  
  437.         a = max(0, pos - t + 1);
  438.         b = pos;
  439.  
  440.         for(i = a;i <= b;i++) positions.insert(i);
  441.  
  442.     }
  443.  
  444.     for(auto i : positions)
  445.     {
  446.  
  447.         if(n <= i+t-1) break;
  448.  
  449.         if(queryHash(sts, 1, 0, n-1, i, i+t-1).fi == hp) ans--;
  450.         if(queryHash(stt, 1, 0, n-1, i, i+t-1).fi == hp) ans++;
  451.  
  452.     }
  453.  
  454.     positions.clear();
  455.    
  456.     return ans;
  457.  
  458. }
  459.  
  460. int main()
  461. {
  462.  
  463.     ios_base::sync_with_stdio(0);
  464.     cin.tie(0);
  465.     cout.tie(0);
  466.     Init();
  467.  
  468.     int op, l, r, pos, i;
  469.  
  470.     char ch;
  471.  
  472.     string p;
  473.  
  474.     cin >> s;
  475.     n = (int)(s.size());
  476.  
  477.     t = s;
  478.     buildHash(stt, 1, 0, n-1);
  479.  
  480.     cin >> q;
  481.  
  482.     for(i = 0;i < q;i++)
  483.     {
  484.  
  485.         if((i%B) == 0) updateAll();
  486.        
  487.         cin >> op;
  488.  
  489.         if(op == 1)
  490.         {
  491.  
  492.             cin >> pos >> ch;
  493.             pos--;
  494.  
  495.             t[pos] = ch;
  496.             updateHash(stt, 1, 0, n-1, pos);
  497.  
  498.             update.pb({pos, ch});
  499.  
  500.             continue;
  501.  
  502.         }
  503.  
  504.         cin >> l >> r >> p;
  505.         l--;
  506.         r--;
  507.  
  508.         cout << Solv(l, r, p) << endl;
  509.  
  510.     }
  511.    
  512.     return 0;
  513.  
  514. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement