Cod sursa(job #1746256)

Utilizator hrazvanHarsan Razvan hrazvan Data 22 august 2016 23:03:14
Problema Substr Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.99 kb
#include <cstdio>
#include <algorithm>
#define MAXN 16384
#define MAXLG 14
using namespace std;
typedef struct{
  int a, b, p;
}per;
char s[MAXN + 2];
int poz[MAXLG + 1][MAXN], inv[MAXN];
int lcp[MAXN - 1];
int dq[MAXN], st, dr;
per sir[MAXN];

inline bool compar(per a, per b){
  if(a.a < b.a)
    return 1;
  if(a.a > b.a)
    return 0;
  if(a.b < b.b)
    return 1;
  return 0;
}

inline void calcsuff(int n){
  int i, x, j;
  for(i = 0; i < n; i++)
    poz[0][i] = s[i];
  for(i = 1; i <= MAXLG; i++){
    for(j = 0; j < n; j++){
      sir[j].a = poz[i - 1][j];
      if(j + (1 << (i - 1)) < n)
        sir[j].b = poz[i - 1][j + (1 << (i - 1))];
      else
        sir[j].b = 0;
      sir[j].p = j;
    }
    sort(sir, sir + n, compar);
    for(j = 0; j < n; j++)
      inv[j] = sir[j].p;
    x = 0;
    for(j = 1; j < n; j++){
      if(compar(sir[j - 1], sir[j]))
        x++;
       poz[i][sir[j].p] = x;
    }
    poz[i][sir[0].p] = 0;
  }
}

inline void calclcp(int n){
  int i, j, x, a, b;
  for(i = 0; i < n - 1; i++){
    x = 0;
    a = inv[i];
    b = inv[i + 1];
    for(j = MAXLG; j >= 0; j--)
      if(a + x + (1 << j) <= n && b + x + (1 << j) <= n && poz[j][a + x] == poz[j][b + x])
        x += (1 << j);
    lcp[i] = x;
  }
}

int main(){
  FILE *in = fopen("substr.in", "r");
  int n, k, max = 0, i;
  fscanf(in, "%d%d ", &n, &k);
  fgets(s, MAXN + 2, in);
  fclose(in);
  calcsuff(n);
  calclcp(n);
  if(k != 1){
    for(i = 0; i < k - 2; i++){
      while(dr > 0 && lcp[dq[dr - 1]] > lcp[i])
        dr--;
      dq[dr] = i;
      dr++;
    }
    for(i = k - 1; i < n - 1; i++){
      while(dr > 0 && lcp[dq[dr - 1]] > lcp[i])
        dr--;
      dq[dr] = i;
      dr++;
      if(i - dq[st] >= k)
        st++;
      if(lcp[dq[st]] > max)
        max = lcp[dq[st]];
    }
  }
  FILE *out = fopen("substr.out", "w");
  if(k != 1)
    fprintf(out, "%d", max);
  else
    fprintf(out, "%d", n);
  fclose(out);
  return 0;
}