Cod sursa(job #1763986)

Utilizator andrei_diaconu11Andrei C. Diaconu andrei_diaconu11 Data 24 septembrie 2016 21:07:10
Problema Substr Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.53 kb
#include <stdio.h>
#include <ctype.h>
#define MOD2 666013
#define MOD1 467312
#define baza 63
using namespace std;
int sum1[16385], sum2[16385], h[16384/2+1], next[16384/2+1], ap[16384/2+1], liste[MOD1], n, a;

int search(int r1, int r2){
  int j;
  for(j=liste[r1];j!=0 && h[j]!=r2;j=next[j]);
  return j;
}

int max(int a, int b){
  if(a>b)
    return a;
  return b;
}

void add(int r1, int r2){
  int poz;
  poz=search(r1,r2);
  if(poz!=0)
    ap[poz]++;
  else{
    h[a]=r2;
    next[a]=liste[r1];
    liste[r1]=a;
    ap[a]=1;
    a++;
  }
}

int cauta(int L){
  int i, rez, pow1, pow2;
  pow1=pow2=1;
  for(i=0;i<L;i++){
    pow1=(pow1*baza)%MOD1;
    pow2=(pow2*baza)%MOD2;
  }
  a=1;
  for(i=L;i<=n;i++)
    add((1LL*sum1[i]-1LL*sum1[i-L]*pow1+1LL*MOD1*MOD1)%MOD1,(1LL*sum2[i]-1LL*sum2[i-L]*pow2+1LL*MOD2*MOD2)%MOD2);
  rez=0;
  for(i=1;i<a;i++){
    rez=max(ap[i],rez);
    h[i]=0;
    next[i]=0;
    ap[i]=0;
  }
  for(i=0;i<MOD1;i++)
    liste[i]=0;
  return rez;
}

int transform(char ch){
  if(isupper(ch)!=0)
    return ch-'A'+1;
  if(islower(ch)!=0)
    return ch-'a'+27;
  return ch-'0'+53;
}

int main(){
  int k, i, len, ch;
  FILE *fi=fopen("substr.in", "r"), *fo=fopen("substr.out", "w");
  fscanf(fi, "%d%d", &n, &k);
  fgetc(fi);
  for(i=1;i<=n;i++){
    ch=transform(fgetc(fi));
    sum1[i]=(sum1[i-1]*baza+ch)%MOD1;
    sum2[i]=(sum2[i-1]*baza+ch)%MOD2;
  }
  int pas=1;
  while(pas<n)
    pas*=2;
  len=0;
  for(pas=pas/2;pas>0;pas/=2)
    if(cauta(len+pas)>=k)
      len+=pas;
  fprintf(fo, "%d", len);
  fclose(fi);
  fclose(fo);
  return 0;
}