Sunday, July 28, 2019

[Codemarshal] F. Find the Substrings

Author            : Dipu Kumar Mohanto 
                    CSE, Batch - 6
                    BRUR.
Problem Statement : F. Find the Substrings
Source            : Codemarshal
                    ACM-ICPC 2018 Preliminary
Category          : String, Data Structure
Algorithm         : Suffix Automata, Number of distinct substring
Verdict           : Accepted

  1. #include "bits/stdc++.h"  
  2. using namespace std;  
  3.   
  4. #define ll            long long int  
  5. #define endl          '\n'  
  6.   
  7. static const int maxn = 1e6 + 5;  
  8. static const ll mod = 1e9 + 7;  
  9. static const int Max = 1e6 + 7;  
  10.   
  11. int N;  
  12. ll Tree[maxn];  
  13.   
  14. ll add(ll a, ll b)  
  15. {  
  16.       a = (a + b + mod) % mod;  
  17.       return a;  
  18. }  
  19.   
  20. void update(int pos, ll val)  
  21. {  
  22.       while (pos <= N)  
  23.       {  
  24.             Tree[pos] = add(Tree[pos], val);  
  25.             pos += (pos & -pos);  
  26.       }  
  27. }  
  28.   
  29. void rangeUpdate(int l, int r, ll val)  
  30. {  
  31.       update(l, val);  
  32.       update(r + 1, -val);  
  33. }  
  34.   
  35. ll query(int pos)  
  36. {  
  37.       ll sum = 0;  
  38.       while (pos > 0)  
  39.       {  
  40.             sum = add(sum, Tree[pos]);  
  41.             pos -= (pos & -pos);  
  42.       }  
  43.       return sum;  
  44. }  
  45.   
  46. struct state  
  47. {  
  48.       int len, link;  
  49.       map <charint> next;  
  50. } st[Max * 2];  
  51.   
  52. int sz, last;  
  53.   
  54. void init()  
  55. {  
  56.       sz = last = 0;  
  57.       st[0].len = 0;  
  58.       st[0].link = -1;  
  59.       st[0].next.clear();  
  60.       for (int i = 1; i < Max * 2; i++)  
  61.       {  
  62.             st[i].len = 0;  
  63.             st[i].link = 0;  
  64.             st[i].next.clear();  
  65.       }  
  66.       ++sz;  
  67. }  
  68.   
  69. void szExtend(char c)  
  70. {  
  71.       int l, r;  
  72.       int cur = sz++;  
  73.       st[cur].len = st[last].len + 1;  
  74.       int p;  
  75.       for (p = last; p != -1 && !st[p].next.count(c); p = st[p].link)  
  76.       {  
  77.             st[p].next[c] = cur;  
  78.       }  
  79.       if (p == -1)  
  80.       {  
  81.             st[cur].link = 0;  
  82.       }  
  83.       else  
  84.       {  
  85.             int q = st[p].next[c];  
  86.             if (st[p].len + 1 == st[q].len)  
  87.             {  
  88.                   st[cur].link = q;  
  89.             }  
  90.             else  
  91.             {  
  92.                   int clone = sz++;  
  93.                   st[clone].len = st[p].len + 1;  
  94.                   st[clone].next = st[q].next;  
  95.                   st[clone].link = st[q].link;  
  96.                   for ( ; p != -1 && st[p].next[c] == q; p = st[p].link)  
  97.                   {  
  98.                         st[p].next[c] = clone;  
  99.                   }  
  100.                   l = st[ st[q].link ].len;  
  101.                   r = st[q].len;  
  102.                   assert(l+1 <= r);  
  103.                   rangeUpdate(l+1, r, -1);  
  104.                   st[q].link = st[cur].link = clone;  
  105.                   l = st[ st[q].link ].len;  
  106.                   r = st[q].len;  
  107.                   assert(l+1 <= r);  
  108.                   rangeUpdate(l+1, r, 1);  
  109.                   l = st[ st[clone].link ].len;  
  110.                   r = st[clone].len;  
  111.                   assert(l+1 <= r);  
  112.                   rangeUpdate(l+1, r, 1);  
  113.             }  
  114.       }  
  115.       l = st[ st[cur].link ].len;  
  116.       r = st[cur].len;  
  117.       assert(l+1 <= r);  
  118.       rangeUpdate(l+1, r, 1);  
  119.       last = cur;  
  120. }  
  121.   
  122. ll power[Max];  
  123. ll powerSum[Max];  
  124. ll sum[Max];  
  125. ll cumsum[Max];  
  126.   
  127. int main()  
  128. {  
  129.       ios_base::sync_with_stdio(false);  
  130.       cin.tie(nullptr);  
  131.       cout.tie(nullptr);  
  132.       cout << fixed << setprecision(12);  
  133.   
  134. //      #ifndef ONLINE_JUDGE  
  135. //            freopen("in.txt", "r", stdin);  
  136. //      #endif // ONLINE_JUDGE  
  137.   
  138.       power[0] = 1LL;  
  139.       powerSum[0] = 0LL;  
  140.       for (int i = 1; i < Max; i++)  
  141.       {  
  142.             power[i] = (power[i-1] * 26) % mod;  
  143.             powerSum[i] = (powerSum[i-1] + power[i]) % mod;  
  144.       }  
  145.   
  146.       int tc;  
  147.       cin >> tc;  
  148.       for (int tcase = 1; tcase <= tc; tcase++)  
  149.       {  
  150.             string s;  
  151.             cin >> s;  
  152.             int len = s.size();  
  153.             N = len;  
  154.             init();  
  155.             for (char ch : s) szExtend(ch);  
  156.             for (int i = 1; i <= len; i++)  
  157.             {  
  158.                   sum[i] = query(i);  
  159.                   cumsum[i] = add(cumsum[i-1], sum[i]);  
  160.             }  
  161.             cout << "Case " << tcase << ":" << endl;  
  162.             int q;  
  163.             cin >> q;  
  164.             while (q--)  
  165.             {  
  166.                   int l, r;  
  167.                   cin >> l >> r;  
  168.                   ll tsub = (powerSum[r] - powerSum[l-1] + mod) % mod;  
  169.                   ll dsub = (cumsum[r] - cumsum[l-1] + mod) % mod;  
  170.                   ll ans = (tsub - dsub + mod) % mod;  
  171.                   cout << ans << endl;  
  172.             }  
  173.             for (int i = 0; i <= N; i++) Tree[i] = 0;  
  174.       }  
  175. }  

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.