Cod sursa(job #788684)

Utilizator SchumiDumitru Andrei Georgian Schumi Data 15 septembrie 2012 16:26:47
Problema PScPld Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.07 kb
#include <cassert>
#include <cstdio>

#include <algorithm>
using namespace std;

const int N = 1000005;

int n;
int d[N * 2];
char c;
char text[N * 2];
long long sol;

int extinde(int x, int y) {
	int len = y - x + 1;
	int i = x - (y - x) - 1;
	int j = y + 1;
	while (i > 0 && j <= n && text[i] == text[j]) {
		--i;
		++j;
		++len;
	}
	
	return len;
}

int main() {
	assert(freopen("pscpld.in", "r", stdin) != NULL);
	assert(freopen("pscpld.out", "w", stdout) != NULL);
	
	scanf("%s", text + 1);
	n = strlen(text + 1);
	
	for (int i = 2 * n + 1; i > 0; --i)
		if (i % 2 == 1)
			text[i] = '#';
		else
			text[i] = text[i / 2];
	n = 2 * n + 1;
	
	int j = 1;
	d[1] = 1;
	for (int i = 2; i <= n; ++i) {
		int iPrim = j - (i - j);
		
		if ((iPrim - d[iPrim] + 1 <= j - d[j]+ 1) || (d[j] + j - 1 <= i)) {
			d[i] = extinde(i, max(i, j + d[j] - 1));
			j = i;
		} else
			d[i] = d[iPrim];
	}
	
	for (int i = 1; i <= n; ++i)
		if (d[i] % 2 == 0)
			sol += d[i] / 2;
		else
			sol += (d[i] - 1) / 2;
	
	printf("%lld\n", sol);
	
	return 0;
}