Advertisement
Manioc

frequency with sa

Aug 3rd, 2018
197
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.21 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define MAX 100007
  3.  
  4. using namespace std;
  5.  
  6. struct state{
  7.     int link, len, clone, pos;
  8.     map<char, int> next;
  9.     vector<int> parents;
  10. } sa[2*MAX];
  11.  
  12. char s[MAX], t[MAX];
  13. int sz, last;
  14. void init(){
  15.     last = 0;
  16.     sa[0].link = -1;
  17.     sa[0].len = 0;
  18.     sz = 1;
  19. }
  20.  
  21. void add(char c){
  22.     int cur = sz++;
  23.     sa[cur].len = sa[last].len + 1;
  24.     sa[cur].pos = sa[last].len;
  25.     for(; last != -1 && !sa[last].next.count(c); last = sa[last].link) sa[last].next[c] = cur;
  26.  
  27.     if(last == -1) sa[cur].link = 0;
  28.     else{
  29.         int q = sa[last].next[c];
  30.         if(sa[q].len == sa[last].len + 1) sa[cur].link = q;
  31.         else{
  32.             int clone = sz++;
  33.             sa[clone].len = sa[last].len + 1;
  34.             sa[clone].pos = sa[q].pos;
  35.             sa[clone].link = sa[q].link;
  36.             sa[clone].clone = true;
  37.             sa[clone].next = sa[q].next;
  38.             for(; last != -1 && sa[last].next[c] == q; last = sa[last].link) sa[last].next[c] = clone;
  39.             sa[cur].link = sa[q].link = clone;
  40.         }
  41.     }
  42.     last = cur;
  43. }
  44.  
  45. vector<int> l;
  46. void dfs(int id, int size){
  47.     if(!sa[id].clone) l.push_back(sa[id].pos);
  48.     for(int i = 0; i < sa[id].parents.size(); i++) dfs(sa[id].parents[i], size);
  49. }
  50.  
  51. int qnt;
  52. void process(int size){
  53.     int i = 0, v = 0;
  54.     for(; i < size; i++) {
  55.         if(!sa[v].next.count(t[i])){
  56.             printf("-1\n");
  57.             return;
  58.         }
  59.         v = sa[v].next[t[i]];
  60.     }
  61.     l.clear();
  62.     dfs(v, size);
  63.     sort(l.begin(), l.end());
  64.     if(l.size() >= qnt){
  65.         int ans = 100000000;
  66.         //for(i = 0; i < l.size(); i++) cout << l[i] << " ";
  67.         //cout << endl;
  68.         for(i = qnt-1; i < l.size(); i++){
  69.             ans = min(ans, l[i]-l[i-qnt+1]+size);
  70.         }
  71.         printf("%d\n", ans);
  72.         return;
  73.     }
  74.     printf("-1\n");
  75. }
  76. int main(){
  77.     scanf(" %s", s);
  78.     int xuxu = strlen(s);
  79.     init(); for(int i = 0; i < xuxu; i++) add(s[i]);
  80.  
  81.     for(int i = 1; i < sz; i++){
  82.         sa[sa[i].link].parents.push_back(i);
  83.     }
  84.    
  85.     int cases; scanf("%d", &cases);
  86.     while(cases--){
  87.         scanf("%d %s", &qnt,t);
  88.         process(strlen(t));
  89.     }
  90.     return 0;
  91. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement