Cod sursa(job #612403)

Utilizator AndreiRSStatescu Andrei Rares AndreiRS Data 7 septembrie 2011 14:29:07
Problema Divk Scor 10
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.28 kb
#include <stdio.h>

const int DIMN = 500005, DIMK = 100005;
struct nod { int p, i; nod *u; } *L[DIMK];
int N, K, Lmin, Lmax;
long long S[DIMN], C;

void addnod (int r, int i)
{
	nod *q = new nod;
	q->i = i;
	q->u = L[r];
	L[r] = q;
}

void cit ()
{
	freopen ("divk.in", "r", stdin);
	freopen ("divk.out", "w", stdout);
	
	scanf ("%d%d%d%d", &N, &K, &Lmin, &Lmax);
	
	for (int r = 0; r < K; r++)
		L[r] = NULL;	
	
	for (int i = 1; i <= N; i++)
	{
		scanf ("%lld", &S[i]);
		S[i] += S[i-1]; 
	}

	for (int i = N; i >= 1; i--)
		addnod (S[i] % K, i);
	addnod (0, 0);
	
	nod *q;
	for (int r = 0; r < K; r++)
	{
		if (L[r] == NULL)
			continue;
		L[r]->p = 1;
		for (q = L[r]; q->u != NULL; q = q->u)
			q->u->p = q->p;
	}
}

void rez ()
{
	nod *p, *u, *q;
	for (int r = 0; r < K; r++)
	{
		if (L[r] == NULL)
			continue;
		for (p = u = q = L[r], q = q->u; q != NULL; q = q->u)
		{
			for (; u->u != q && q->i - u->u->i > Lmin; u = u->u);				
			for (; p->u != q && q->i - p->i > Lmax; p = p->u);				
			
			if (u->p < p->p)
				continue;
			if (u == p && q->i - p->p >= Lmin && q->i - p->p <= Lmax)
			{
				C++;
				continue;
			}
			C += u->p - p->p + 1;
		}
	}
	
	printf ("%lld", C);
}

int main ()
{
	cit ();
	rez ();
	
	return 0;
}