Cod sursa(job #253274)

Utilizator 630r63Ilinca George Mihai 630r63 Data 5 februarie 2009 16:55:34
Problema Substr Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.35 kb
 #include <cstdio>  
 #include <cstring>  
 #include <algorithm>  
   
 using namespace std;  
   
 struct keys {  
     int x, y, p;  
   
     keys (int _x = 0, int _y = 0, int _p = 0) :  
     x(_x), y(_y), p(_p) {}  
   
     bool operator==(keys b) {  
         return x == b.x && y == b.y;  
     }  
 };  
   
 const int LGMAX = 14;  
 const int NMAX = (1 << LGMAX) + 1;  
   
 int N, K, L;  
 char S[NMAX];  
 int A[LGMAX][NMAX], V[NMAX];  
 keys T[NMAX], C[NMAX];  
   
 void read(void) {  
     FILE *fin = fopen("substr.in", "rt");  
   
     fscanf(fin, " %d %d", &N, &K);  
   
     fscanf(fin, " %s", S);  
   
     fclose(fin);  
 }  
   
 void rsort(keys T[], int t) {  
     int i;  
   
     memset(V, 0x00, sizeof(V));  
   
     for (i = 0; i < N; ++i)  
         ++V[ t ? T[i].y : T[i].x ];  
       
     for (i = 1; i <= N; ++i)  
         V[i] += V[i - 1];  
       
     for (i = N-1; i >= 0; --i)  
         C[ -- V[ t ? T[i].y : T[i].x ] ] = T[i];  
   
     memcpy(T, C, sizeof(C));  
 }  
   
 void build(void) {  
     int i, is, stp, t;  
   
     for (i = 0; i < N; ++i)  
         V[ (int) S[i] ] = 1;  
     for (i = 1; i < 256; ++i)  
         V[i] += V[i-1];  
     for (i = 0; i < N; ++i)  
         A[0][i] = V[ (int) S[i] ];  
   
     t = V[255];  
     for (stp = 1, is = 1; stp < N && t != N; stp <<= 1, ++is) {  
           
         for (i = 0; i < N; ++i)  
             T[i] = keys(A[is-1][i], (i + stp < N ? A[is-1][i+stp] : 0), i);  
   
         rsort(T, 1);  
         rsort(T, 0);  
   
         A[is][ T[0].p ] = t = 1;  
         for (i = 1; i < N; ++i)  
             A[is][ T[i].p ] = t += !(T[i] == T[i-1]);  
     }  
     L = is - 1;  
 }  
   
 int lcp(int x, int y) {  
     if (x == y) return N - x;  
     int k, ret = 0;  
   
     for (k = L; k >= 0; --k)  
         if (A[k][x] == A[k][y])  
             ret += 1 << k, x += 1 << k, y += 1 << k;  
   
     return ret;  
 }  
   
 void write(void) {  
     FILE *fout = fopen("substr.out", "wt");  
     int i, R = 0;  
   
     for (i = 0; i <= N - K; ++i)  
         R = max(R, lcp(T[i].p, T[i + K - 1].p));  
   
     fprintf(fout, "%d\n", R);  
   
     fclose(fout);  
 }  
   
 int main(void) {  
   
     read();  
   
     build();  
   
     write();  
   
return 0;}