Skip to content

Instantly share code, notes, and snippets.

@walac
Last active December 26, 2015 17:09
Show Gist options
  • Save walac/7184693 to your computer and use it in GitHub Desktop.
Save walac/7184693 to your computer and use it in GitHub Desktop.
MSUBSTR spoj problem
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_LEN 3000
#define AUX_LEN (MAX_LEN * 2 + 1)
int fn[AUX_LEN];
char aux[AUX_LEN+1];
int p[AUX_LEN];
char s[MAX_LEN+1];
/*
* Uses manacher's algorithm
*/
static int
min(int a, int b)
{
return a < b ? a : b;
}
static int
manacher(const char *s)
{
const size_t slen = strlen(s);
const size_t aux_len = slen * 2 + 2;
int max = 0;
aux[0] = '\xff';
for (int i = 1, j = 0; i < aux_len; ++j, i += 2) {
aux[i] = s[j];
aux[i+1] = '\xff';
}
aux[aux_len-1] = '\0';
memset(p, 0, aux_len * sizeof(int));
memset(fn, 0, aux_len * sizeof(int));
int c = 0, r = 0, len;
for (int i = 1; i < aux_len-1; ++i) {
const int i_ = 2*c-i;
len = r > i ? min(r-i, p[i_]) : 0;
while ((i+1+len) < aux_len && (i-1-len) >= 0 && aux[i+1+len] == aux[i-1-len])
++len;
fn[len]++;
if (len > max)
max = len;
p[i] = len;
if (i + len > r) {
c = i;
r = i + len;
}
}
return max;
}
int
main(void)
{
int len;
char s[4000];
int m;
scanf("%d\n", &len);
while (len--) {
gets(s);
m = manacher(s);
printf("%d %d\n", m, fn[m]);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment