Как решить ультрастандартную задачу?

Revision ru1, by Felix_Mate, 2018-08-17 15:57:08

Получаю ВА1 в тренировке: 2012-2013 Тренировка СПбГУ B #17 Строки (по материалам контеста Сергея Копелиовича)

Код (суффмассив украл с e-maxx):

include

using namespace std;

const int maxlen = 1000 * 1005; const int alphabet = 256;

int n; int p[maxlen], cnt[maxlen], c[maxlen]; int pn[maxlen], cn[maxlen], lcp[maxlen]; char s[maxlen];

int main() { FILE * fp = fopen("suffarray.in", "r"); n = 0; while (fscanf(fp, "%c", &s[n]) != EOF) n++; s[++n] = char(0); fclose(fp);

memset(cnt, 0, alphabet * sizeof(int));
for (int i = 0; i<n; ++i) ++cnt[s[i]];
for (int i = 1; i<alphabet; ++i) cnt[i] += cnt[i - 1];
for (int i = 0; i<n; ++i) p[--cnt[s[i]]] = i;
c[p[0]] = 0;
int classes = 1;
for (int i = 1; i<n; ++i)
{
    if (s[p[i]] != s[p[i - 1]])  ++classes;
    c[p[i]] = classes - 1;
}

for (int h = 0; (1 << h)<n; ++h)
{
    for (int i = 0; i<n; ++i)
    {
       pn[i] = p[i] - (1 << h);
       if (pn[i] < 0)  pn[i] += n;
    }
    memset(cnt, 0, classes * sizeof(int));
    for (int i = 0; i<n; ++i) ++cnt[c[pn[i]]];
    for (int i = 1; i<classes; ++i) cnt[i] += cnt[i - 1];
    for (int i = n - 1; i >= 0; --i) p[--cnt[c[pn[i]]]] = pn[i];
    cn[p[0]] = 0;
    classes = 1;
    for (int i = 1; i<n; ++i)
    {
       int mid1 = (p[i] + (1 << h)) % n, mid2 = (p[i - 1] + (1 << h)) % n;
       if (c[p[i]] != c[p[i - 1]] || c[mid1] != c[mid2]) ++classes;
       cn[p[i]] = classes - 1;
    }
    memcpy(c, cn, n * sizeof(int));
}

n--;
fp = fopen("suffarray.out", "w");

for (int i = 0; i < n; i++) p[i] = p[i + 1];

for (int i = 0; i<n-1; i++) fprintf(fp, "%d ", p[i] + 1);
fprintf(fp, "%d", p[n-1] + 1);
fclose(fp);

return 0;

}

History

 
 
 
 
Revisions
 
 
  Rev. Lang. By When Δ Comment
ru1 Russian Felix_Mate 2018-08-17 15:57:08 1722 Первая редакция (опубликовано)