Cod sursa(job #2431951)

Utilizator NineshadowCarapcea Antonio Nineshadow Data 21 iunie 2019 13:22:38
Problema Substr Scor 70
Compilator c-64 Status done
Runda Arhiva de probleme Marime 2.3 kb
// Suffix array
#include <stdio.h>
#include <string.h>
#include <stdlib.h>


#define MAXN 65536
#define MAXLG 17

char str[MAXN];

typedef struct _entry {
    int nr[2], p;
} entry;

entry L[MAXN];

int P[MAXLG][MAXN], n, stp, q, lg, V[MAXN];

int cmp(const void *_a, const void *_b) {
    if(_a == NULL || _b == NULL)
        return 0;

    entry *a = (entry*)_a;
    entry *b = (entry*)_b;
    
    return a->nr[0] == b->nr[0] ? (a->nr[1] > b->nr[1]) : (a->nr[0] > b->nr[0]);
}


void print_p() {
    for(int k = 0; k < stp; ++k) {
        for(int i = 0; i < n; ++i) {
            printf("%d ", P[k][i]);
        }
        printf("\n");
    }
    printf("\n");
}

void print_suffix() {
    for(int i = 0; i < n; ++i) {
        for(int j = 0; j < n; ++j) {
            if(P[lg][j] == i) {
                printf("%d, %d: %s\n", i, j, str + j);
            }
        }
    }
}

void build_suffix() {
    int i, cnt;
    for(i = 0; i < n; ++i) {
        P[0][i] = str[i] - 'a';
    }

    for(stp = 1, cnt = 1; cnt < n; cnt <<= 1, ++stp) {
        for(i = 0; i < n; ++i) {
            L[i].nr[0] = P[stp - 1][i];
            L[i].nr[1] = i + cnt < n ? P[stp - 1][i + cnt] : -1;
            L[i].p = i;
        }
        qsort(L, n, sizeof(entry), cmp);
        for (i = 0; i < n; ++i)
            P[stp][L[i].p] = (i > 0 && L[i].nr[0] == L[i - 1].nr[0] && L[i].nr[1] == L[i - 1].nr[1])? P[stp][L[i - 1].p] : i;
    }
    lg = stp - 1;

    for(i = 0; i < n; i++)
		V[P[lg][i]]=i;
  
    
}

void print_v() {
    for(int i = 0; i < n; ++i) {
        printf("%d ", V[i]);
    }
    printf("\n");
}


int LCP(int x, int y)
{
	int i,sol;
	sol = 0;
	if(x == y)
		return n;
	for(i = lg; i >= 0; i--)
		if(P[i][x] == P[i][y]) {
			sol = sol + (1 << i);
			x = x + (1 << i);
			y = y + (1 << i);
			if(x > n || y > n)
				break;
		}
	return sol;
}
 


int main() {
    FILE *in = fopen("substr.in", "r");
    fscanf(in, "%d %d\n", &n, &q);
    fgets(str, MAXN, in);

    build_suffix();
    //print_p();

    int max = 0;
    for(int i = 0; i < n - q; ++i) {
        int prefix = LCP(V[i], V[i + q - 1]);
        //printf("%s %s: %d\n", str + V[i], str + V[i + q - 1], prefix);
        if(prefix > max) {
            max = prefix;
        }
    }
    //print_v();
    FILE *out = fopen("substr.out", "w");
    fprintf(out, "%d\n", max);
    fclose(out);
    


}