Cod sursa(job #1764930)

Utilizator andreicoman299Coman Andrei andreicoman299 Data 26 septembrie 2016 09:10:38
Problema Substr Scor 100
Compilator cpp Status done
Runda cerculdeinfo-lectia1-hashuri.rabinkarp Marime 2.89 kb
#include <stdio.h>
#include <stdlib.h>
#define MOD 666013
#define MOD2 666019
#define MAXN 16384

#define BUF_SIZE 16384
char buf[BUF_SIZE];
int pbuf=BUF_SIZE;
FILE*fi,*fo;
inline char nextch(){
    if(pbuf==BUF_SIZE){
        fread(buf, BUF_SIZE, 1, fi);
        pbuf=0;
    }
    return buf[pbuf++];
}
inline int nextnum(){
    int a=0;
    char c=nextch();
    while((c<'0' || c>'9') && c!='-')
        c=nextch();
    int semn=1;
    if(c=='-'){
        semn=-1;
        c=nextch();
    }
    while('0'<=c && c<='9'){
        a=a*10+c-'0';
        c=nextch();
    }
    return a*semn;
}
class Hash{
    public: int k=0, next[MAXN+1], lista[MOD];
    int val[MAXN+1];
    int d[MAXN+1];
    inline void insert(int val1, int val2, int frecventa){
        k++;
        val[k]=val2;
        d[k]=frecventa;
        next[k]=lista[val1%MOD];
        lista[val1%MOD]=k;
    }
    inline void erase(int element){
        int p=lista[element%MOD];
        if(p==0)
            return ;
        if(val[p]==element){
            lista[element%MOD]=next[lista[element%MOD]];
            return ;
        }
        while((next[p]!=0)&&(val[next[p]]!=element))
            p=next[p];
        if(next[p]!=0)
            next[p]=next[next[p]];
    }
    inline int find(int val1, int val2){
        int p=lista[val1%MOD];
        while(p!=0 && val[p]!=val2)
            p=next[p];
        if(p!=0)
            return p;
        return 0;
    }
} H;

int n;
char v[MAXN+1];
int r1[MAXN+1], r2[MAXN+1];
inline int maxapp(int len){
    int pow1, pow2;
    pow1=pow2=1;
    for(int i=0;i<len;i++){
        pow1=(pow1*63)%MOD;
        pow2=(pow2*63)%MOD2;
    }
    int max=-1;
    for(int i=len;i<=n;i++){
        int val1=(1LL*r1[i]-1LL*r1[i-len]*pow1+1LL*MOD*MOD)%MOD;
        int val2=(1LL*r2[i]-1LL*r2[i-len]*pow2+1LL*MOD2*MOD2)%MOD2;
        if(!H.find(val1, val2))
            H.insert(val1, val2, 1);
        else
            H.d[H.find(val1, val2)]++;
        if(H.d[H.find(val1, val2)]>max)
            max=H.d[H.find(val1, val2)];
    }
    for(int i=0;i<MOD;i++)
        H.lista[i]=0;
    H.k=0;
    return max;
}

int main(){
    fi=fopen("substr.in","r");
    fo=fopen("substr.out","w");
    n=nextnum();
    int k=nextnum();
    for(int i=1;i<=n;i++){
        v[i]=nextch();
        if('0'<=v[i] && v[i]<='9')
            v[i]=v[i]-'0'+1;
        else if('A'<=v[i] && v[i]<='Z')
            v[i]=v[i]-'A'+1+10;
        else
            v[i]=v[i]-'a'+1+36;
        r1[i]=(r1[i-1]*63+v[i])%MOD;
        r2[i]=(r2[i-1]*63+v[i])%MOD2;
    }
    int st=1, dr=n, m;
    while(st<dr){
        m=(st+dr)/2;
        if(maxapp(m)>=k)
            st=m+1;
        else
            dr=m;
    }

    if(maxapp(st)>=k){
        fprintf(fo,"%d", st);
    }
    else
        fprintf(fo,"%d", st-1);

    fclose(fi);
    fclose(fo);
    return 0;
}