Cod sursa(job #2007743)

Utilizator silkMarin Dragos silk Data 3 august 2017 22:04:33
Problema Substr Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.04 kb
#include <cstdio>
#include <algorithm>
#include <queue>
#define NMax 16386
#define Log 15
using namespace std;

struct sub{ int x,y,id; } a[NMax+1];
deque<int> v[256];
char s[NMax+1];
int P[Log+1][NMax+1];
int suff[NMax+1];
int d[NMax+1];
int N,K,T;

bool cmp(const sub A, const sub B)
{
    if(A.x == B.x) return A.y < B.y;
    return A.x < B.x;
}

void Suffix()
{
    int i,j,t,k,p,idx;

    for(i = 1; i <= N; ++i) v[ s[i-1] ].push_back(i);
    for(j = i = 0; i < 256; ++i)
    {
        if(!v[i].empty()) ++j;
        while(!v[i].empty())
        {
            P[0][ v[i].front() ] = j;
            v[i].pop_front();
        }
    }

    for(k = 1, i = 0; 1 << i < N; ++i, k <<= 1)
    {
        idx = 0;
        for(j = 1; j <= N; ++j)
        {
            a[j].id = j;
            a[j].x = P[i][j];
            if(j + k <= N) a[j].y = P[i][j+k];
            else a[j].y = -1;
        }

        sort(a+1, a+N+1, cmp);
        for(j = 1; j <= N; )
        {
            P[i+1][ a[j++].id ] = ++idx;
            while(a[j-1].x == a[j].x && a[j-1].y == a[j].y) P[i+1][ a[j++].id ] = idx;
        }
    }

    T = i;
}

int lcp(int x, int y)
{
    int i,res=0;

    for(i = T; i >= 0 && x <= N && y <= N; --i)
        if(P[i][x] == P[i][y])
        x += 1 << i, y += 1 << i, res += 1 << i;

    return res;
}

inline bool good(int f)
{
    int i,cnt=1;

    for(i = 1; i < N; ++i)
    {
        cnt = (d[i] >= f ? ++cnt : 1);
        if(cnt >= K) return 1;
    }

    return 0;
}

int main(){
    FILE* fin = fopen("substr.in","r");
    FILE* fout = fopen("substr.out","w");

    int i,st,dr,mid,res=0;

    fscanf(fin,"%d %d\n",&N,&K);
    fscanf(fin,"%s",s);

    Suffix();
    for(i = 1; i <= N; ++i) suff[ P[T][i] ] = i;
    for(i = 1; i < N; ++i) d[i] = lcp(suff[i], suff[i+1]);
    for(st = 1, dr = N; st <= dr; )
    {
        mid = (st+dr)/2;
        if(!good(mid)) dr = mid-1;
        else { res = mid; st = mid+1; }
    }

    fprintf(fout,"%d\n",res);


return 0;
}