Advertisement
Guest User

Untitled

a guest
Sep 26th, 2016
234
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.13 KB | None | 0 0
  1. #include <cstdio>
  2. #include <vector>
  3. #include <algorithm>
  4. #include <map>
  5. #include <queue>
  6. using namespace std;
  7.  
  8. const int N = (int)5e4 + 100;
  9. const int K = 10;
  10. const int LOG = 16;
  11.  
  12. int n;
  13. char s[N];
  14. int a[N];
  15. int lst[K];
  16.  
  17. struct state {
  18.     int len, link, cnt;
  19.     map<int,int> next;
  20. };
  21.  
  22. state st[N*2*11];
  23. int sz, last;
  24. int deg[N*2*11];
  25. int sa_pos[N];
  26. int orig_pos[N];
  27. int sparse[LOG][N*2*11];
  28.  
  29. void sa_init() {
  30.     sz = last = 0;
  31.     st[0].len = 0;
  32.     st[0].link = -1;
  33.     ++sz;
  34. }
  35.  
  36. void sa_extend (int from, int to) {
  37.     for (int i = from; i <= to; i++) {
  38.         int c = a[i];
  39.         if (st[last].next.count(c)) {
  40.             last = st[last].next[c];
  41.         }
  42.         else {
  43.             int cur = sz++;
  44.             st[cur].len = st[last].len + 1;
  45.             int p;
  46.             for (p=last; p!=-1 && !st[p].next.count(c); p=st[p].link)
  47.                 st[p].next[c] = cur;
  48.             if (p == -1)
  49.                 st[cur].link = 0;
  50.             else {
  51.                 int q = st[p].next[c];
  52.                 if (st[p].len + 1 == st[q].len)
  53.                     st[cur].link = q;
  54.                 else {
  55.                     int clone = sz++;
  56.                     st[clone].len = st[p].len + 1;
  57.                     st[clone].next = st[q].next;
  58.                     st[clone].link = st[q].link;
  59.                     for (; p!=-1 && st[p].next[c]==q; p=st[p].link)
  60.                         st[p].next[c] = clone;
  61.                     st[q].link = st[cur].link = clone;
  62.                 }
  63.             }
  64.             last = cur;
  65.         }
  66.         sa_pos[i] = last;
  67.     }
  68. }
  69.  
  70. void solve()
  71. {
  72.     sa_init();
  73.     for (int i = 0; i < K; i++)
  74.         lst[i] = -1;
  75.     for (int i = 0; i < n; i++)
  76.     {
  77.         if (lst[a[i]] != -1) {
  78.             a[lst[a[i]]] = i - lst[a[i]] + 1;
  79.             last = (lst[a[i]] == 0 ? 0 : sa_pos[lst[a[i]] - 1]);
  80.             sa_extend(lst[a[i]], i-1);
  81.         }
  82.         lst[a[i]] = i;
  83.         a[i] = 1;
  84.         sa_extend(i, i);
  85.         orig_pos[i] = sa_pos[i];
  86.         st[sa_pos[i]].cnt++;
  87.     }
  88.  
  89.     for (int i = 1; i < sz; i++)
  90.         sparse[0][i] = st[i].link;
  91.  
  92.     for (int k = 1; k < LOG; k++)
  93.         for (int i = 0; i < sz; i++)
  94.             sparse[k][i] = sparse[k-1][sparse[k-1][i]];
  95.  
  96.     queue<int> q;
  97.     for (int i=1; i<sz; i++) deg[st[i].link]++;
  98.     for (int i=1; i<sz; i++) if (deg[i] == 0) q.push(i);
  99.     while (!q.empty()) {
  100.         int k = q.front();
  101.         if (k > 0) {
  102.             st[st[k].link].cnt += st[k].cnt;
  103.             if ( --deg[st[k].link] == 0 ) q.push(st[k].link);
  104.         }
  105.         q.pop();
  106.     }
  107. }
  108.  
  109. int query(int p, int len)
  110. {
  111.     for (int k = LOG-1; k >= 0; k--) {
  112.         if (st[sparse[k][p]].len >= len)
  113.             p = sparse[k][p];
  114.     }
  115.     return st[p].cnt;
  116. }
  117.  
  118. int query()
  119. {
  120.     int l, r;
  121.     scanf("%d%d", &l, &r);
  122.     int len = r - l + 1;
  123.     int p = orig_pos[r-1];
  124.     return query(p, len);
  125. }
  126.  
  127. int main()
  128. {
  129.     int q;
  130.     scanf("%d%d", &n, &q);
  131.     scanf(" %s ", s);
  132.     for (int i = 0; i < n; i++)
  133.         a[i] = (int)(s[i] - 'a');
  134.     solve();
  135.     while(q--)
  136.         printf("%d\n", query());
  137.  
  138.     return 0;
  139. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement