Cod sursa(job #479595)

Utilizator cont_de_testeCont Teste cont_de_teste Data 24 august 2010 15:50:02
Problema Numarare Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.88 kb
#include <cstdio>
#include <algorithm>

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

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;
    }

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

    for (i = N - 1; i > 0; i--) {
        h2[i] = (h2[i + 1] * baza + D[i]) % 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]) {

            while (left <= right) {
                m = (left + right) / 2;
                //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) {
                    left = m + 1;
                    sol = m;
                } else
                    right = m - 1;
            }
        }

        rez = rez + sol + 1;
    }

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


    return 0;
}