Advertisement
Guest User

Untitled

a guest
Sep 26th, 2016
351
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.62 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <vector>
  5. #include <algorithm>
  6. #include <string>
  7. #include <cstring>
  8. using namespace std;
  9.  
  10. const int N = (int)5e4 + 100;
  11. const int K = 10;
  12. const int LOG = 16;
  13.  
  14. typedef pair<int, int> pii;
  15. #define mp make_pair
  16. typedef vector<pii> vec;
  17. typedef pair<vec, int> pvi;
  18.  
  19. char s[N];
  20. int a[N];
  21. int lst[K];
  22. int SA[N], nSA[N];
  23. int col[N], ncol[N];
  24. int b[N];
  25. int revSA[N];
  26. int LCP[N];
  27. int sparse[LOG][N];
  28. int p2[N];
  29. int n;
  30. vector<int> specPos[N];
  31. pvi arr[N];
  32. int revArr[N];
  33.  
  34. void buildSA()
  35. {
  36.     a[n++] = 0;
  37.     for (int i = 0; i <= n; i++)
  38.         b[n] = 0;
  39.     for (int i = 0; i < n; i++)
  40.         b[a[i] + 1]++;
  41.     for (int i = 0; i < n; i++)
  42.         b[i + 1] += b[i];
  43.     for (int i = 0; i < n; i++)
  44.         SA[b[a[i]]++] = i;
  45.     col[SA[0]] = 0;
  46.     for (int i = 1; i < n; i++)
  47.     {
  48.         col[SA[i]] = col[SA[i - 1]];
  49.         if (a[SA[i]] != a[SA[i - 1]])
  50.             col[SA[i]]++;
  51.     }
  52.     for (int len = 1; col[SA[n - 1]] < n - 1; len <<= 1)
  53.     {
  54.         for (int i = 0; i <= n; i++)
  55.             b[i] = 0;
  56.         for (int i = 0; i < n; i++)
  57.             b[col[i] + 1]++;
  58.         for (int i = 0; i < n; i++)
  59.             b[i + 1] += b[i];
  60.         for (int i = 0; i < n; i++)
  61.         {
  62.             int p = (SA[i] - len + 4 * n) % n;
  63.             nSA[b[col[p]]++] = p;
  64.         }
  65.         for (int i = 0; i < n; i++)
  66.             SA[i] = nSA[i];
  67.         ncol[SA[0]] = 0;
  68.         for (int i = 1; i < n; i++)
  69.         {
  70.             int p = SA[i], q = SA[i - 1];
  71.             ncol[p] = ncol[q];
  72.             if (col[p] != col[q] || col[(p + len) % n] != col[(q + len) % n])
  73.                 ncol[p]++;
  74.         }
  75.         for (int i = 0; i < n; i++)
  76.             col[i] = ncol[i];
  77.     }
  78.     for (int i = 0; i < n; i++)
  79.         revSA[SA[i]] = i;
  80.     int curLCP = 0;
  81.     for (int i = 0; i < n; i++)
  82.     {
  83.         int p = revSA[i];
  84.         if (p == n - 1)
  85.         {
  86.             LCP[p] = curLCP = 0;
  87.             continue;
  88.         }
  89.         curLCP = max(0, curLCP - 1);
  90.         int q = SA[p + 1];
  91.         while(i + curLCP < n && q + curLCP < n && a[i + curLCP] == a[q + curLCP])
  92.             curLCP++;
  93.         LCP[p] = curLCP;
  94.     }
  95.     n--;
  96.     for (int i = 0; i < n; i++)
  97.         sparse[0][i] = LCP[i];
  98.     for (int k = 1; k < LOG; k++)
  99.         for (int i = 0; i + (1 << k) <= n; i++)
  100.             sparse[k][i] = min(sparse[k - 1][i], sparse[k - 1][i + (1 << (k - 1))]);
  101.     for (int i = 2; i < N; i++)
  102.         p2[i] = p2[i >> 1] + 1;
  103.     return;
  104. }
  105.  
  106. int getSparse(int l, int r)
  107. {
  108.     int k = p2[r - l];
  109.     return min(sparse[k][l], sparse[k][r - (1 << k)]);
  110. }
  111. int getLCP(int l, int r)
  112. {
  113.     if (l == r)
  114.         return n - SA[l];
  115.     if (l > r) swap(l, r);
  116.     return getSparse(l, r);
  117. }
  118.  
  119. int getPosInSA(int pos, int len)
  120. {
  121.     pos = revSA[pos];
  122.     int l = -1, r = pos;
  123.     while(r - l > 1)
  124.     {
  125.         int x = (l + r) / 2;
  126.         if (getLCP(x, pos) >= len)
  127.             r = x;
  128.         else
  129.             l = x;
  130.     }
  131.     return r;
  132. }
  133.  
  134. void solve()
  135. {
  136.     for (int i = 0; i < K; i++)
  137.         lst[i] = -1;
  138.     for (int i = n - 1; i >= 0; i--)
  139.     {
  140.         if (lst[a[i]] != -1)
  141.             a[lst[a[i]]] = lst[a[i]] - i + 1;
  142.         lst[a[i]] = i;
  143.         a[i] = 1;
  144.         specPos[i].clear();
  145.         for (int j = 0; j < K; j++)
  146.             if (lst[j] != -1)
  147.                 specPos[i].push_back(lst[j]);
  148.         sort(specPos[i].begin(), specPos[i].end());
  149.         specPos[i].push_back(n);
  150.     }
  151.     buildSA();
  152.     for (int i = 0; i < n; i++)
  153.     {
  154.         vec cur;
  155.         for (int j = 0; j < (int)specPos[i].size() - 1; j++)
  156.         {
  157.             int curPos = specPos[i][j] + 1;
  158.             int len = specPos[i][j + 1] - curPos;
  159.             cur.push_back(mp(getPosInSA(curPos, len), len));
  160.         }
  161.         arr[i] = mp(cur, i);
  162.     }
  163.     sort(arr, arr + n);
  164.     /*
  165.     for (int i = 0; i < n; i++)
  166.     {
  167.         printf("%d : ", arr[i].second);
  168.         for (pii p : arr[i].first)
  169.             printf("(%d %d) ", p.first, p.second);
  170.         printf("\n");
  171.     }
  172.     */
  173.     for (int i = 0; i < n; i++)
  174.         revArr[arr[i].second] = i;
  175.     return;
  176. }
  177.  
  178. bool equalToLen(vec A, vec B, int len)
  179. {
  180.     for (int i = 0;; i++)
  181.     {
  182.         if (len <= 0) return true;
  183.         if (i >= (int)A.size() || i >= (int)B.size()) return false;
  184.         len--;
  185.         if (len > min(A[i].second, B[i].second))
  186.         {
  187.             if (A[i] != B[i]) return false;
  188.             len -= A[i].second;
  189.             continue;
  190.         }
  191.         return getLCP(A[i].first, B[i].first) >= len;
  192.     }
  193.     throw;
  194. }
  195.  
  196. int query(int p, int len)
  197. {
  198.     int l = -1, r = p;
  199.     while(r - l > 1)
  200.     {
  201.         int x = (l + r) / 2;
  202.         if (equalToLen(arr[x].first, arr[p].first, len))
  203.             r = x;
  204.         else
  205.             l = x;
  206.     }
  207.     int L = r;
  208.     l = p;
  209.     r = n;
  210.     while(r - l > 1)
  211.     {
  212.         int x = (l + r) / 2;
  213.         if (equalToLen(arr[x].first, arr[p].first, len))
  214.             l = x;
  215.         else
  216.             r = x;
  217.     }
  218.     int R = r;
  219.     return R - L;
  220. }
  221.  
  222. int query()
  223. {
  224.     int l, r;
  225.     scanf("%d%d", &l, &r);
  226.     l--;
  227.     int len = r - l;
  228.     int p = revArr[l];
  229.     return query(p, len);
  230. }
  231.  
  232. int main()
  233. {
  234. //  freopen("input.txt", "r", stdin);
  235. //  freopen("output.txt", "w", stdout);
  236.  
  237.     int q;
  238.     scanf("%d%d", &n, &q);
  239.     scanf(" %s ", s);
  240.     for (int i = 0; i < n; i++)
  241.         a[i] = (int)(s[i] - 'a');
  242.     solve();
  243.     while(q--)
  244.         printf("%d\n", query());
  245.  
  246.     return 0;
  247. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement