Cod sursa(job #2007741)

Utilizator silkMarin Dragos silk Data 3 august 2017 21:53:57
Problema Substr Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.19 kb
#include <cstdio>
#include <queue>
#define NMax 16386
#define Log 15
using namespace std;

deque<int> q1[NMax+1];
deque<int> q2[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;

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)
    {
        for(j = 1; j <= N; ++j)
            if(j + k <= N) q1[ P[i][j+k] ].push_back(j);
            else q1[0].push_back(j);

        for(j = 0; j <= N; ++j)
            while(!q1[j].empty())
            {
                idx = q1[j].front();
                q2[ P[i][idx] ].push_back(idx);
                q1[j].pop_front();
            }

        for(t = j = 0; j <= N; ++j)
        {
            if(!q2[j].empty()) ++t, p = q2[j].front();
            while(!q2[j].empty())
            {
                idx = q2[j].front();
                P[i+1][idx] = (P[i][p+k] == P[i][idx+k] ? t : ++t);
                q2[j].pop_front();
                p = 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;
}