Cod sursa(job #1765735)

Utilizator BarbumateiBarbu Matei Barbumatei Data 26 septembrie 2016 22:35:49
Problema Substr Scor 100
Compilator c Status done
Runda cerculdeinfo-lectia1-hashuri.rabinkarp Marime 1.67 kb
#include <stdio.h>
#include <stdlib.h>
#define MAXN 16384
#define B 211
#define MOD1 665019
#define MOD2 9478671

int lista[MOD1], next[MAXN+1], f[MAXN+1], val[MAXN+1], adev[MAXN+1], m, rasp, n;
char v[MAXN+1];

inline void insert(int x, int y){
  int poz;
  poz=lista[x];
  while(poz && val[poz]!=y)
    poz=next[poz];
  if(val[poz]==y){//daca l-am gasit
    f[poz]++;
    if(f[poz]>rasp)
      rasp=f[poz];
    return;
  }
  ///practic ce facem e sa inseram toata sirurile in hash
  ///cu frecvente si sa verificam daca siruri codificat cu x si y are o frecventa mai mare ca
  ///numarul de aparitii maxim a unui sir de lungime l, raspunsul va fi frecventa noului sir
  val[++m]=y;
  adev[m]=x;
  f[m]=1;
  next[m]=lista[x];
  lista[x]=m;
}

inline int apar(int l){
  int p1, p2, h1a, h2a, i;
  m=0; rasp=1;
  p1=p2=1; h1a=h2a=0;
  for(i=0; i<l-1; i++){
    h1a=(h1a*B+v[i])%MOD1;
    h2a=(h2a*B+v[i])%MOD2;
    p1=(p1*B)%MOD1;
    p2=(p2*B)%MOD2;
  }
  for(i=l-1; i<n; i++){
    h1a=(h1a*B+v[i])%MOD1;
    h2a=(h2a*B+v[i])%MOD2;
    insert(h1a, h2a);
    h1a=(h1a-(v[i-l+1]*p1)%MOD1+MOD1)%MOD1;
    h2a=(h2a-(v[i-l+1]*p2)%MOD2+MOD2)%MOD2;
  }
  for(i=1; i<=m; i++)
    lista[adev[i]]=0;
  return rasp;
}

int main(){
  int k, nr, p, i;
  FILE *fin, *fout;
  fin=fopen("substr.in", "r");
  fout=fopen("substr.out", "w");
  fscanf(fin, "%d%d ", &n, &k);
  for(i=0; i<n; i++)
    v[i]=fgetc(fin);
  p=1<<16; nr=0;
  for(; p; p>>=1){///facem o cautare binara
    if(nr+p<=n && apar(nr+p)>=k)///daca intra in vector si daca apare de cel putin k ori
      nr+=p;
  }
  fprintf(fout, "%d\n", nr);
  fclose(fin);
  fclose(fout);
    return 0;
}