Cod sursa(job #479605)

Utilizator CezarMocanCezar Mocan CezarMocan Data 24 august 2010 16:00:54
Problema Numarare Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.53 kb
#include <cstdio>
#include <algorithm>

const int maxN = 100100;
const int baza = 30000;
const int mod = 32771;

using namespace std;

char s[10 * maxN];
int V[maxN], D[maxN];
int h1[maxN], h2[maxN], powerB[maxN];
int N, rez;

int main() {
	int i, j;
	freopen("numarare.in", "r", stdin);
	freopen("numarare.out", "w", stdout);

	scanf("%d ", &N);

	fgets(s, 1000000, stdin);

	j = 0;
	for (i = 1; i <= N; i++) {
		int sgn = 1;
		if (s[j] == '-') {
			sgn = -1;
			j++;
		}

		while (s[j] >= '0' && s[j] <= '9') {
			V[i] = V[i] * 10 + (s[j] - 48);
			j++;
		}

		while (s[j] == ' ')
			j++;

		V[i] *= sgn;
	}

	for (i = 1; i < N; i++) {
		D[i] = V[i] - V[i + 1] + 200000;
	}

	for (i = 1; i < N; i++) {
		h1[i] = (h1[i - 1] * baza + D[i]) % mod;
	}

	for (i = N - 1; i > 0; i--) {
		h2[i] = (h2[i + 1] * baza + D[i]) % mod;
	}

	powerB[0] = 1;
	for (i = 1; i <= N; i++)
		powerB[i] = (powerB[i - 1] * baza) % mod;


	for (i = 1; i < N; i++) {
		int left, right, m, sol = 0;
		left = 1; right = min(i, N - i - 1);

		if (D[i - 1] == D[i + 1]) {

			m = 0;
			for (int t = 17; t >= 0; t--) {
				m = m + (1 << t);
				
				if (i - m < 0)	{ m -= (1 << t); continue; }
				if (i + m >= N)	{ m -= (1 << t); continue; }
				//o sa am de la i - m  la i + m 

				int R1, R2;
				R1 = h1[i] - ((h1[i - m - 1] * powerB[m + 1]) % mod);
				if (R1 < 0)	R1 += mod;

				R2 = h2[i] - ((h2[i + m + 1] * powerB[m + 1]) % mod);
				if (R2 < 0)	R2 += mod;

				if (R1 != R2) 
					m -= (1 << t);
			}

			sol = m;
		}

		rez = rez + sol + 1;
	}

	printf("%d\n", rez);


	return 0;
}