Advertisement
Manioc

kth de size n

Sep 16th, 2019
273
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.34 KB | None | 0 0
  1. // by: Emiso
  2. #include <bits/stdc++.h>
  3. #define MAX 1007
  4. #define ALP 26
  5.  
  6. using namespace std;
  7. typedef long long ll;
  8.  
  9. int C(char c) { return c - 'a'; }
  10.  
  11. struct aho {
  12.     int parent[MAX], suffix[MAX], to[MAX][ALP], super[MAX];
  13.     char from[MAX];
  14.     int id[MAX], cnt, built;
  15.     long long ending[MAX], lazy[MAX];
  16.  
  17.     int new_node(int _parent = 0, char _from = ' ') {
  18.         parent[cnt] = _parent; from[cnt] = _from; id[cnt] = -1;
  19.         suffix[cnt] = super[cnt] = ending[cnt] = lazy[cnt] = 0;
  20.         for(int i = 0; i < ALP; i++) to[cnt][i] = 0;
  21.         return cnt++;
  22.     }
  23.  
  24.     aho() {
  25.         cnt = built = 0;
  26.         new_node();
  27.     }
  28.  
  29.     int add(string &word, int _id = 0) {
  30.         int node = 0;
  31.         for(int i = 0; i < word.size(); i++) {
  32.             int nxt = C(word[i]);
  33.             if(!to[node][nxt]) to[node][nxt] = new_node(node, word[i]);
  34.             node = to[node][nxt];
  35.         }
  36.         ending[node]++;
  37.         if(id[node] == -1) id[node] = _id;
  38.         return id[node];
  39.     }
  40.  
  41.     void build() {
  42.         built = 1;
  43.         queue<int> q;
  44.         for(int i = 0; i < ALP; i++)
  45.             if(to[0][i]) q.push(to[0][i]);
  46.  
  47.         while(!q.empty()) {
  48.             int v = q.front(); q.pop();
  49.             if(parent[v]) suffix[v] = to[suffix[parent[v]]][C(from[v])];
  50.  
  51.             if(id[v] != -1) super[v] = v;
  52.             else super[v] = super[suffix[v]];
  53.  
  54.             ending[v] += ending[suffix[v]];
  55.             for(int i = 0; i < ALP; i++) {
  56.                 if(!to[v][i]) to[v][i] = to[suffix[v]][i];
  57.                 else q.push(to[v][i]);
  58.             }
  59.         }
  60.     }
  61.  
  62.     long long search_text(string &text) {
  63.         if(!built) build();
  64.         int prefix = 0;
  65.         long long count = ending[0];
  66.         for(char c : text) {
  67.             prefix = to[prefix][C(c)];
  68.             count += ending[prefix];
  69.         }
  70.         return count;
  71.     }
  72.  
  73.     /// array of number of occurrences of pattern with id = i
  74.     void search_text(string &text, int *ans) {
  75.         if(!built) build();
  76.         int prefix = 0;
  77.         for(char c : text) {
  78.             prefix = to[prefix][C(c)];
  79.             for(int u = super[prefix]; u; u = super[suffix[u]])
  80.                 ans[id[u]]++;
  81.         }
  82.     }
  83.  
  84.     void search_text_linear(string &text, int *ans) { /// O(N+M)
  85.         if(!built) build();
  86.         int prefix = 0;
  87.         for(char c : text) {
  88.             prefix = to[prefix][C(c)];
  89.             lazy[prefix]++;
  90.         }
  91.         push_lazy(ans);
  92.     }
  93.  
  94.     void push_lazy(int *ans) {
  95.         vector<int> deg(cnt, 0);
  96.         for(int i = 1; i < cnt; i++)
  97.             deg[suffix[i]]++;
  98.  
  99.         queue<int> fila;
  100.         for(int i = 1; i < cnt; i++)
  101.             if(deg[i] == 0) fila.push(i);
  102.  
  103.         while(!fila.empty()) {
  104.             int u = fila.front(); fila.pop();
  105.  
  106.             if(id[u] != -1) ans[id[u]] += lazy[u];
  107.             lazy[suffix[u]] += lazy[u];
  108.  
  109.             deg[suffix[u]]--;
  110.             if(suffix[u] && deg[suffix[u]] == 0) fila.push(suffix[u]);
  111.         }
  112.     }
  113. } dict;
  114.  
  115. ll dp[107][MAX][2];
  116. int n;
  117. ll solve(int falt, int state, int flag){
  118.     if(falt >= n) return dp[falt][state][flag] = flag;
  119.  
  120.     if(dp[falt][state][flag] != -1) return dp[falt][state][flag];
  121.  
  122.     ll ans = 0;
  123.     for(int i = 0; i < 26; i++){
  124.         int prox = dict.to[state][i];
  125.         ans += solve(falt+1, prox, flag || dict.ending[prox]);
  126.         ans = min((ll) 1e18 + 7LL, ans);
  127.     }
  128.  
  129.     //return ans;
  130.     return dp[falt][state][flag] = ans;
  131. }
  132.  
  133. void search(int state, int size, int flag, int k){
  134.     if(size == n) return;
  135.     ll acum = 0LL;
  136.     for(int i = 0; i < 26; i++){
  137.         int prox = dict.to[state][i];
  138.         int fflag = flag || dict.ending[prox];
  139.    
  140.         if(acum + dp[size+1][prox][fflag] < k) acum += dp[size+1][prox][fflag];
  141.         else{
  142.             putchar( (char)(i+'a') );
  143.             search(prox, size+1, fflag, k-acum);
  144.             break;
  145.         }
  146.     }
  147. }
  148.  
  149. char st[MAX];
  150. int main() {
  151.     int k; scanf("%d %d", &n, &k);
  152.     int q; scanf("%d", &q);
  153.     memset(dp, -1, sizeof dp);
  154.     for(int i = 1; i <= q; i++){
  155.         scanf("%s", st);
  156.         string s(st);
  157.         dict.add(s, i);
  158.     }
  159.     dict.build();
  160.     ll bigu = solve(0, 0, 0);
  161.     if(k > bigu) printf("unnamed baby :(");
  162.     else search(0, 0, 0, k);
  163.     printf("\n");
  164.     return 0;
  165. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement