Cod sursa(job #446511)

Utilizator voyagerSachelarie Bogdan voyager Data 26 aprilie 2010 01:48:23
Problema PScPld Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 2 kb
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <ctime>
#define FIN "pscpld.in"
#define FOUT "pscpld.out"
#define NMAX 1000010

using namespace std;

char sz[NMAX];
int lg[NMAX * 2], dim = 0;
bool mid[NMAX * 2];

int main()
{
	long long ret = 0, cnt = 0;
	int tmp, i, j, l, r, il, ir;
	char c;
	FILE *fin = freopen(FIN, "r", stdin), *fout = freopen(FOUT, "w", stdout);

	for (c = getchar(); c >= 'a' && c <= 'z'; c = getchar()) sz[++dim] = c;

	for (i = dim; i; --i)
	{
		if (sz[i] != sz[i-1])
		{
			lg[(i << 1) - 1] = 1;
			mid[(i << 1) - 1] = true;
			continue;
		}
		tmp = 1; l = 0;
		for (; i; --i)
		{
			if (sz[i] != sz[i-1]) break;
			lg[(i << 1) - 1] = tmp;
			lg[i << 1] = tmp - 1;
			tmp += 2;
			++l;
		}
		tmp = 1;
		for (j = i; j < i + ((l + 1) >> 1); ++j, tmp += 2)
		{
			lg[(j << 1) - 1] = tmp;
			lg[j << 1] = tmp + 1;
		}

		if (l & 1) mid[(i + (l >> 1)) << 1] = true;
		else mid[((i + (l >> 1)) << 1) - 1] = true;
	}

	for (i = 1, l, r; i <= (dim << 1) - 1; ++i)
	{
		if (i & 1) l = ((i + 1) >> 1) - ((lg[i] + 1) >> 1) , r = ((i + 1) >> 1) + ((lg[i] + 1) >> 1);
		else l = (i - lg[i]) >> 1, r = ((i + lg[i]) >> 1) + 1;
		
		if (mid[i])
		{
			tmp = l;
			while (l > 0 && (r <= dim))
				if (sz[l] == sz[r]) --l, ++r;
				else break;
			
			lg[i] += (tmp - l) << 1;
			/*++l; --r;
			for (il = (l << 1) - 1, ir = (r << 1) - 1; ir - il > 1; ++il, --ir)
				if (il & 1) lg[ir] = min(lg[il], min(i - il + 1, il - (l << 1)));
				else lg[ir] = min(lg[il], min(i - il + 1, il - (l << 1) + 2));*/
		}

		ret += ((long long)lg[i] + 1) >> 1;
	}
	
	//brute force
	/*for (int i = 1, l, r; i <= dim; ++i)
	{
		l = i; r = i;
		while (l && (r - dim - 1))
		{
			if (sz[l] == sz[r]) ++ret, --l, ++r;
			else break;
		}

		l = i - 1; r = i;
		while (l && (r - dim - 1))
		{
			if (sz[l] == sz[r]) ++ret, --l, ++r;
			else break;
		}
	}*/

	//for (int i = 0; i < 100000; ++i)
	//	printf("a");
	
	printf("%lld\n", ret);
	return 0;
}