Cod sursa(job #1746884)

Utilizator oldatlantianSerban Cercelescu oldatlantian Data 24 august 2016 02:37:01
Problema Substr Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.86 kb
#include <bits/stdc++.h>
using namespace std;

const int NMAX = 22000,
          LMAX = 20;

struct AUX {
    int c1, c2, pos;
};

int len, lg, k;

AUX l[NMAX];
int p[LMAX][NMAX];

char str[NMAX];

bool cmp(const AUX &a, const AUX &b) {
    if(a.c1==b.c1)
        return a.c2<b.c2;
    else
        return a.c1<b.c1;
}

void make_sfx(void) {
    for(int i=0; i<len; ++i)
        p[0][i] = str[i];

    for(lg=1; (1 << lg) < len; ++lg) {
        for(int i=0; i<len; ++i) {
            l[i].pos = i;
            l[i].c1  = p[lg - 1][i];
            if(i + (1 << lg - 1) < len)
                l[i].c2 = p[lg - 1][i + (1 << lg - 1)];
            else
                l[i].c2 = -1;
        }

        sort(l, l+len, cmp);

        for(int i=0; i<len; ++i) {
            if(i && l[i].c1==l[i - 1].c1 && l[i].c2==l[i - 1].c2)
                p[lg][l[i].pos] = p[lg][l[i-1].pos];
            else
                p[lg][l[i].pos] = i;
        }
    } --lg;
}

int lcp(int a, int b) {
    int ant = 0,
          c = a;

    for(int i=lg; i>=0; --i) {
        if(p[i][a]==p[i][b]) {
            a   += 1<<i;
            b   += 1<<i;
            ant += 1<<i;
        }
    }

    return ant;
}

bool check(int val) {
    int dr, ant = 0;

    for(int i=0; i<len-val; ++i) {
        dr = i;
        for(int j=1<<20; j; j>>=1)
            if(dr+j<len && lcp(l[i].pos, l[dr+j].pos)>=val)
                dr+=j;
        ant = max(ant, dr-i+1);
    }

    return (ant >= k);
}

int main(void) {
    freopen("substr.in",  "r", stdin);
    freopen("substr.out", "w", stdout);
    int ant;

    ant = 0;

    scanf("%d%d ",&len,&k);
    gets(str);

    make_sfx();

    for(int i=1<<20; i; i>>=1)
        if(ant+i<=len && check(ant+i))
            ant+=i;

    printf("%d\n",ant);

    fclose(stdin);
    fclose(stdout);
}