Cod sursa(job #131017)

Utilizator savimSerban Andrei Stan savim Data 2 februarie 2008 21:28:23
Problema Divk Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.21 kb
#include <stdio.h>
#define maxn 500010
#define maxk 100010
int p,q,p1,p2,nrtot,i,j,n,k,a,b,m;
int v[maxn],g[maxn],s[maxn],ind[maxn];
int nr[maxk],vine[maxk];
int poz[maxk][2];
int main()
{
	freopen("divk.in","r",stdin);
	freopen("divk.out","w",stdout);
	scanf("%d%d%d%d",&n,&k,&a,&b);
    s[0]=0;
	for (i=1; i<=n; i++)
    {
        scanf("%d",&g[i]);
        ind[i]=0;
		s[i]=(s[i-1]+g[i])%k;
        nr[s[i]]++;
	}

    m=0;poz[0][1]=0;
	for (i=0; i<=k-1; i++)
    if (nr[i]!=0)
    {
		m++;
        poz[m][0]=poz[m-1][1]+1;
		poz[m][1]=poz[m][0]+nr[i]-1;
		ind[m]=poz[m][0]-1;
		vine[i]=m;
	}

	for (i=1; i<=n; i++)
	{
		ind[vine[s[i]]]++;
		v[ind[vine[s[i]]]]=i;
	}
	nrtot=0;
	for (i=1; i<=n; i++)
		if (s[i]==0 && b>=i && i>=a) nrtot++;

	//calcul NlogN
	for (i=1; i<=m; i++)
		for (j=poz[i][0]; j<=poz[i][1]; j++)
		{
			p1=-1;p=j-1;q=poz[i][1]+1;
			while (p+1<q)
			{
				int r=(p+q)/2;
				if (b>=v[r]-v[j] && v[r]-v[j]>=a)
				{
					p1=r;
					q=r;
				}
				else p=r;
			}
			p=j-1;q=poz[i][1]+1;p2=p1-1;
			while (p+1<q)
			{
				int r=(p+q)/2;
				if (b>=v[r]-v[j] && v[r]-v[j]>=a) p2=r;
				p=r;
			}
			nrtot+=p2-p1+1;
		}
	printf("%d\n",nrtot);
	return 0;
}