Advertisement
Manioc

substr

Jul 18th, 2018
261
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.18 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define MAX 200007
  3.  
  4. using namespace std;
  5.  
  6. struct node{
  7.     int next[27];
  8.     long long link, len;
  9. } sa[2*MAX];
  10.  
  11. int sz, last, n;
  12. string palavra;
  13. void init(){
  14.     sz = 1;
  15.     last = 0;
  16.     sa[0].link = -1;
  17.     sa[0].len = 0;
  18.     for(int i = 0; i < 26; i++) sa[0].next[i] = 0;
  19. }
  20.  
  21. void add(int c){
  22.     int cur = sz++;
  23.     sa[cur].len = sa[last].len + 1LL;
  24.    
  25.     for(int i = 0; i < 26; i++) sa[cur].next[i] = 0;
  26.     for(; last != -1 && !sa[last].next[c]; last = sa[last].link) sa[last].next[c] = cur;
  27.  
  28.     if(last == -1) sa[cur].link = 0;
  29.     else{
  30.         int q = sa[last].next[c];
  31.         if(sa[q].len == sa[last].len + 1) sa[cur].link = q;
  32.         else{
  33.             int clone = sz++;
  34.             sa[clone].len = sa[last].len + 1LL;
  35.             sa[clone].link = sa[q].link;
  36.             memcpy(sa[clone].next, sa[q].next, sizeof sa[q].next);
  37.             for(; last != -1 && sa[last].next[c] == q; last = sa[last].link) sa[last].next[c] = clone;
  38.             sa[q].link = sa[cur].link = clone;
  39.         }
  40.     }
  41.     last = cur;
  42. }
  43.  
  44. long long sub(){
  45.     long long ans = 0LL;
  46.     for(int i = 1; i < sz; i++){
  47.         if(sa[sa[i].link].len+1 <= palavra.size()){
  48.             //cout << "[ " << sa[sa[i].link].len+1 << ", " << sa[i].len << " ]\n";
  49.             //cout << sa[i].len-sa[sa[i].link].len << endl;
  50.             if(sa[i].len > palavra.size()) ans -= sa[i].len-palavra.size();
  51.             ans += sa[i].len-sa[sa[i].link].len;
  52.         }
  53.     }
  54.     return ans;
  55. }
  56. int main(){
  57.     cin >> n;
  58.     cin >> palavra;
  59.     long long ans = 0;
  60.     init();
  61.     for(int i = 0; i < palavra.size(); i++) add(palavra[i]-'a');
  62.     for(int i = 0; i < palavra.size(); i++) add(palavra[i]-'a');
  63.     add(26);
  64.     for(int i = palavra.size()-1; i >= 0; i--) add(palavra[i]-'a');
  65.     for(int i = palavra.size()-1; i >= 0; i--) add(palavra[i]-'a');
  66.     ans = sub();
  67.     //init();
  68.     //for(int i = 0; i < palavra.size(); i++) add(palavra[i]-'a');
  69.     //for(int i = palavra.size()-1; i >= 0; i--) add(palavra[i]-'a');
  70.     //cout << sub() << endl;
  71.     //ans -= sub();
  72.     long long parc = (palavra.size()*(palavra.size()+1))/2;
  73.     cout << ans-parc << endl;
  74.     return 0;
  75. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement