Cod sursa(job #1695803)

Utilizator depevladVlad Dumitru-Popescu depevlad Data 27 aprilie 2016 20:21:32
Problema Substr Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.61 kb
#include <fstream>
#include <algorithm>

#define pi pair<int, int>
#define mp make_pair
#define pb push_back
#define fi first
#define se second

using namespace std;

ifstream in("substr.in");
ofstream out("substr.out");

const int N = 20000;
const int LOG = 20;

int n, k, logn;
string str;
int sa[LOG][N], suff[N];
pair<pair<int, int>, int> crt[N];

void buildSuffArr() {
   int i, j, k;
   pair<int, int> pe;

   copy(str.begin(), str.end(), sa[0]);
   for(i = 1; (1 << i) < n; i++) {
      for(j = 0; j < n; j++) {
         pe = make_pair(sa[i - 1][j], -1);
         if(j + (1 << (i - 1)) <= n) pe.second = sa[i - 1][j + (1 << (i - 1))];
         crt[j] = make_pair(pe, j);
      }
      sort(crt, crt + n);
      for(j = k = 0; j < n; j++) {
         if(j > 0 && crt[j].first != crt[j - 1].first) k++;
         sa[i][crt[j].second] = k;
      }
   }

   for(i = 0; i < n; i++) {
      suff[i] = i;
   }
   sort(suff, suff + n, [](int a, int b) { return sa[logn][a] < sa[logn][b]; });
}

int lcp(int i, int j) {
   int q = 0, p;

   for(p = logn; p >= 0; p--) {
      if(max(i, j) + (1 << p) <= n) {
         if(sa[p][i] == sa[p][j]) {
            q |= (1 << p);
            i += (1 << p);
            j += (1 << p);
         }
      }
   }

   return q;
}

int main() {
   int i;

   in >> n >> k;
   in >> str;

   n = str.size();
   logn = 0;
   while((1 << logn) <= n) logn++;
   logn--;

   buildSuffArr();

   int best = 0;
   for(i = 0; i < n - k; i++) {
      best = max(best, lcp(suff[i], suff[i + k - 1]));
   }

   out << best << '\n';
   return 0;
}