Cod sursa(job #1416857)

Utilizator ZenusTudor Costin Razvan Zenus Data 9 aprilie 2015 00:36:54
Problema Hashuri Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.75 kb
// In order to succeed , we must first believe that we can!

#include <fstream>

using namespace std;

#define NMAX 200007
#define LgMAX 19

ifstream f("intervale.in");
ofstream g("intervale.out");

int lg[NMAX] , x[NMAX] , d[NMAX] , rmqM[LgMAX][NMAX] , rmqm[LgMAX][NMAX];
int i,j,N,sol,M,m;

void BuildLog()
{
    for (int i=2;i<=N;++i)
    lg[i] = lg[i>>1] + 1;
}

void BuildMax()
{
    for (i=1;i<=N;++i)
    rmqM[0][i] = x[i];

    for (int len=1;len<=lg[N];++len)
    for (int i=1;i <= N - (1<<len) + 1;++i)
    rmqM[len][i] = max ( rmqM[len-1][i] , rmqM[len-1][i+(1<<(len-1))]);
}

void BuildMin()
{
    for (i=1;i<=N;++i)
    rmqm[0][i] = x[i];

    for (int len=1;len<=lg[N];++len)
    for (int i=1;i <= N - (1<<len) + 1;++i)
    rmqm[len][i] = min ( rmqm[len-1][i] , rmqm[len-1][i+(1<<(len-1))]);
}

int qM(int x,int y)
{
    int k = lg[y-x+1];

    return max(rmqM[k][x],rmqM[k][y-(1<<k)+1]);
}

int qm(int x,int y)
{
    int k = lg[y-x+1];

    return min(rmqm[k][x],rmqm[k][y-(1<<k)+1]);
}

int main()
{

ifstream f("intervale.in");
ofstream g("intervale.out");

f >> N;

for (i=1;i<=N;++i)
f >> x[i];

BuildLog();
BuildMax();
BuildMin();

for (i=1;i<=N;++i)
if (d[i-1] >= 2) d[i] = d[i-1] - 1;
else
{
    j = i+1;
    while (j <= N && (x[j] - x[j-1] == 1 || x[j] - x[j-1] == -1))
    j += 1;

    d[i] = j - i;
}

for (i=1;i<=N;++i)
{
    sol += 1ll * d[i];

    for (j = i + d[i] ; j <= N ;)
    {
        m = qm(i,j);
        M = qM(i,j);

        // m = minim[i,j];
        // M = maxim[i,j];

        if (M - m == j - i)
        {
            sol += d[j];
            j += d[j];
        }
        else
        j = i + M - m ;
    }
}

g << sol << '\n';

return 0;
}