Cod sursa(job #177069)

Utilizator DorinOltean Dorin Dorin Data 12 aprilie 2008 10:39:32
Problema Distincte Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.63 kb
# include <stdio.h>

# define input "distincte.in"
# define output "distincte.out"

# define max 100001

# define mij ((st+dr)>>1)

int a[max],at[max],ant,i,j;
int arb[16][max];
long long s[16][max];
int n, m, k, v[max], x, y;
int x1,x2,y1,y2,K;
long long sum;

void build(int nv,int st,int dr)
{
	 if(st == dr)
	 {
		   arb[nv][st] = v[st];
		   s[nv][st] = a[st];
		   return;
	 }
	 build(nv+1,st,mij);
	 build(nv+1,mij+1,dr);

	 for(k = st,i = st,j = mij+1; i <= mij && j <= dr;)
	 {
		   if(arb[nv+1][i] > arb[nv+1][j])
		   {
			  if(k == st)
				  s[nv][k] = s[nv+1][j];
			  else
			  {
                  if(i == st)                  
    				  s[nv][k] = s[nv+1][j];
			      else
			         s[nv][k] = s[nv+1][i-1] + s[nv+1][j];
              }
			  arb[nv][k++] = arb[nv+1][j++];
		   }
		   else
		   {
			  if(k == st)
				  s[nv][k] = s[nv+1][i];
			  else
			  {
				  if(j == mij+1 )
				     s[nv][k] = s[nv+1][i];
	              else
	                 s[nv][k] = s[nv+1][i] + s[nv+1][j-1];
              }
              arb[nv][k++] = arb[nv+1][i++];
           }
     }
	 while(i <= mij)
	 {
		s[nv][k] = s[nv+1][i] + s[nv+1][j-1];
		arb[nv][k++] = arb[nv+1][i++];
	 }
	 while(j <= dr)
	 {
        s[nv][k] = s[nv+1][i-1] + s[nv+1][j];
		arb[nv][k++] = arb[nv+1][j++];
	 }
}

int search(int st, int dr, int e, int * c)
{
    int step;
    for( step = 1; step <= dr-st+1; step <<= 1);
    
	for( i = st-1; step; step >>= 1)
         if(i+step <= dr && c[i+step] <= e) i+=step;
    return i;
}

void query(int nv, int st, int dr)
{
     if(x1 <= st && dr <= x2)
	 {
		   if( y2 < arb[nv][st] || y1 > arb[nv][dr])   return;
		   if( y2 >= arb[nv][dr] && y1 <= arb[nv][st])
		   {
				sum += s[nv][dr];
				return;
		   }
		   int p1,p2;
		   p1 = search(st, dr, y1-1, arb[nv]) + 1;
		   p2 = search(st, dr, y2, arb[nv]);
		   if(p1 == st)  sum += s[nv][p2];
		   else   sum += s[nv][p2] - s[nv][p1-1];
		   return;
	 }
     if( mij >= x1 ) query(nv+1,st,mij);
     if( mij < x2 ) query(nv+1,mij+1,dr);     
}

int main()
{
    freopen(input, "r", stdin);
    freopen (output, "w", stdout);
    
	scanf("%d%d%d",&n, &m, &K);

	for( i = 1; i<= n; i++)
	   at[i] = n+1;

	for(i = 1; i<= n; i++)
	{
		  scanf("%d",&a[i]);
		  v[i] = at[a[i]];
		  at[a[i]] = i;
	}
	build (0, 1, n);

	while( K-- )
    {
           scanf("%d %d",&x1,&x2);
           
		   y1 = 1;   y2 = x1-1;  sum = 0;
		   if(y2)    query(0, 1, n);           
           y1 = y2 = n+1;
           query(0, 1, n);
           
           printf("%lld\n",sum);
    }
    return 0;
}