Cod sursa(job #265538)

Utilizator luk17Luca Bogdan luk17 Data 23 februarie 2009 23:46:06
Problema Arbori indexati binar Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.74 kb

#include<stdio.h>
#define NMAX 100001
int n,a[NMAX],s[NMAX],v[NMAX],M;
inline int Minim(int a, int b) {
       if ( a < b ) return a;
       return b;
}

int nr0(int x)
{
	int contor=0;
	while(x&&x%2==0)
	{
		contor++;
		x>>=1;
	}
	return 1<<contor;
}
void op0(int poz,int val)
{
	int nr_de_0=nr0(poz);
	while(poz<=n)
	{
		v[poz]+=val;
		nr_de_0++;
		poz+=nr0(poz);
	}
}
int  op1(int dr)
{
	int s=0,poz=dr;
	while(poz>0)
	{
		s+=v[poz];
		poz-=nr0(poz);
	}

	return s;
}
int op2(int Sum)
{
 int pos = n+1, B,S;
    int limst=0, limdr=n+1;
            
    B = n;
    S = op1(B);
            
    if ( S == Sum ) pos = n;
            
    while ( B )
    {
          B = (limst+limdr)>>1;
          S = op1(B);
                  
          if ( S > Sum )
          {
               if ( limdr > B ) limdr = B;
               B -= 1;
          }
          else if ( S == Sum ) pos = Minim(pos,B), limdr = B, B -= 1;
          else
          {
              if ( limst < B ) limst = B;
              B += 1;
          }
                  
          if ( B <= limst ) break;
          if ( B >= limdr ) break;
    }
            
    if ( pos == n+1 ) return -1;
    return pos;
}
int main()
{
	int i,x,y,z;

	freopen("aib.in","r",stdin);
	freopen("aib.out","w",stdout);
	scanf("%d%d",&n,&M);

	for(i=1;i<=n;i++)
	{
		scanf("%d",a+i);
		s[i]=s[i-1]+a[i];
	}

	for(i=1;i<=n;i++)
		v[i]=s[i]-s[i-nr0(i)];
	
	for(i=1;i<=M;i++)
	{
		scanf("%d",&x);
		if(x==0)
		{
			scanf("%d%d",&y,&z);
			op0(y,z);

		}
		else
			if(x==1)
			{
				scanf("%d%d",&y,&z);
				printf("%d\n",op1(z)-op1(y-1));
			}
			else
			{
				scanf("%d",&y);
				printf("%d\n",op2(y));
			}
	}

	return 0;
}