Cod sursa(job #466777)

Utilizator ProtomanAndrei Purice Protoman Data 27 iunie 2010 14:40:23
Problema Numarare Scor 30
Compilator cpp Status done
Runda Stelele Informaticii 2010, clasele X-XII, Ziua 1 Marime 1.67 kb
#include <algorithm>
#include <stdio.h>
#include <time.h>

#define MAX 100010
#define ll long long

using namespace std;

int n, gs;
ll sol, solGs;
int d[MAX], x[MAX];

inline void cautaBin(int fr, int ls, int loc)
{
    if (fr > ls || gs)
        return;

    int med = (fr + ls) / 2;

    int ok = 1;
    if (d[loc - med] == d[loc + med])
    {
        if (med != fr)
            for (int i = 1; i <= 5; i++)
            {
                int l = rand() % (med - fr) + 1;
                if (d[loc - fr - l] != d[loc + fr + l])
                    ok = 0;
            }
    }
    else ok = 0;

    if (ok)
    {
        for (; d[loc - solGs] == d[loc + solGs] && solGs <= med; solGs++);

        if (solGs <= med)
            gs = 1;
    }

    if (ok)
        cautaBin(med + 1, ls, loc);
    else cautaBin(fr, med - 1, loc);
}

int main()
{
    srand(time(0));
    freopen("numarare.in", "r", stdin);
    freopen("numarare.out", "w", stdout);

    scanf("%d", &n);

    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &x[i]);

        d[i - 1] = x[i - 1] - x[i];
    }

    if (n <= 1000)
    {
        for (int i = 1; i < n; i++)
        {
            int st = i, dr = i;
            for (; d[st] == d[dr] && st && dr < n; st--, dr++);

            sol += i - st;
        }

        printf("%lld\n", sol);
    }
    else
    {
        sol = 0;
        for (int i = 1; i < n; i++)
        {
            gs = 0, solGs = 0;
            cautaBin(0, min(i - 1, n - 1 - i), i);

            sol += solGs;
        }

        printf("%lld\n", sol);
    }

    fclose(stdin);
    fclose(stdout);
    return 0;
}