Cod sursa(job #466610)

Utilizator stocarulCosmin-Mihai Tutunaru stocarul Data 27 iunie 2010 11:56:37
Problema Numarare Scor 30
Compilator cpp Status done
Runda Stelele Informaticii 2010, clasele X-XII, Ziua 1 Marime 1.38 kb
#include<cstdio>
#define infile "numarare.in"
#define outfile "numarare.out"
#define nmax 100013
#define inf (~(1<<31))

using namespace std;

int v[nmax]; //vectorul cu numerele
int d[nmax]; //d[i]=v[i]-v[i-1]
int ls[nmax]; //ls[i]=cate elemente pe pozitii consecutive (in stanga) sunt egale cu d[i]
int ld[nmax]; //ld[i]=cate elemente pe pozitii consecutive (in dreapta) sun egale cu d[i]
int n; //numarul de numere
long long count; //numarul de secvente

inline int min(int a, int b)
{
	if(a<b) return a; return b;
}

void read()
{
	int i;
	scanf("%d\n",&n);
	for(i=1;i<=n;++i)
		scanf("%d",&v[i]);
}

void init()
{
	int i;
	
	//sa nu ne incurcam
	d[1]=ls[1]=ld[1]=inf;

	//construim pe d
	for(i=2;i<=n;++i)
		d[i]=v[i]-v[i-1];

	//construim pe ls
	for(i=2;i<=n;++i)
		if(d[i]==d[i-1])
			ls[i]=ls[i-1]+1;
		else ls[i]=1;

	//construim pe ld
	for(i=n;i>1;--i)
		if(d[i]==d[i+1])
			ld[i]=ld[i+1]+1;
		else ld[i]=1;
}

void solve()
{
	int i,st,dr;

	//luam fiecare ceintre, centru fiind inainte de pozitia i
	for(i=2;i<=n;++i)
	{
		++count; //secventa de lungime 2
		st=i-1, dr=i+1;
		while(d[st]==d[dr])
		{
			count+=min(ls[st],ld[dr]);
			if(ls[st]==ld[dr]) st-=ls[st], dr+=ld[dr];
			else break;
		}
	}
}

void write()
{
	printf("%lld\n",count);
}

int main()
{
	freopen(infile,"r",stdin);
	freopen(outfile,"w",stdout);

	read();
	init();
	solve();
	write();

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