Cod sursa(job #2024397)

Utilizator AlexandruLuchianov1Alex Luchianov AlexandruLuchianov1 Data 20 septembrie 2017 16:32:57
Problema Substr Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.13 kb
#include <iostream>
#include <fstream>
#include <algorithm>

using namespace std;
ifstream in ("substr.in");
ofstream out ("substr.out");
int const nmax = 16384;
int const logmax = 14;
char line[1 + nmax];

struct str{
  int ind;///poz pe care ne aflam in s
  int x;///partea 1 din eticheta
  int y;///partea 2 din eticheta
  bool operator < (str a) const{
    if(x != a.x){
      return x < a.x;
    } else
      return y < a.y;
  }
  bool operator == (str a) const{
    return (x == a.x) && (y == a.y);
  }
};
int n, k;
int p[logmax + 1][nmax + 1];
str v[nmax + 1];
void suffix_array(){
  for(int i = 1 ; i <= n ;i++){
    if('0' <= line[i] && line[i] <= '9'){
      p[0][i] = line[i] - '0';
    } else if('a' <= line[i] && line[i] <= 'z'){
      p[0][i] = line[i] - 'a' + 10;
    } else{
      p[0][i] = line[i] - 'A' + 10 + 26;
    }
    //cout<<p[0][i]<<" ";
  }
 // cout<<'\n';
  for(int i = 1 ; i <= logmax ;i++){
    ///cream noile etichete si sortam
    for(int j = 1 ; j <= n ;j++){
      int x = 0;
      if(j + (1 << (i - 1)) <= n){
        x = p[i - 1][j + (1 << (i - 1))];
      }
      v[j] = {j ,p[i - 1][j] , x};
    }
    sort(v + 1 , v + n + 1);

    ///punem numerele in p,cu noua lor ethicheta compusa
    int nr = 1;
    for(int j = 1 ; j <= n;){
      int ind = j;///poz in v
      while(ind <= n && v[j] == v[ind]){
        p[i][v[ind].ind] = nr;
        ind++;
      }
      nr++;
      j = ind;
    }
  }
}
int alike(int x , int y){
  int answer = 0;///lungimea maxima de asemanare a lui x cu y
  for(int i = logmax ;0 <= i ;i--){
    int jump = (1 << i);
    if(x + jump - 1<= n && y + jump - 1 <= n && p[i][x] == p[i][y]){///daca sunt valide si similare la jump caractere
      //cout<<jump<<" "<<p[i][x]<<" "<<p[i][y]<<'\n';
      x += jump;
      y += jump;
      answer += jump;
    }
  }
  return answer;
}
int main()
{
  in>>n>>k>>(line + 1);
  suffix_array();
  int answer = 0;

  for(int i = 1 ; i <= n - k + 1;i++){
    int result = alike(v[i].ind , v[i + k - 1].ind);
    if(answer < result){
      answer = result;
    }
  }
  out<<answer;
  return 0;
}