Cod sursa(job #402737)

Utilizator adrianraduleaRadulea Adrian adrianradulea Data 24 februarie 2010 09:10:38
Problema Arbori indexati binar Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.2 kb
#include<stdio.h>
#include<math.h>
FILE *f,*g;
long v[101000],n,suma1,suma2,l1,l2,ok,mij,ss,m,i,x,y,l,varb; int zv[101000],pp[30];

void add(long i,long x)
{ v[i]+=x;
  while(i<n)
   { i=i+pp[zv[i]];
     if(i<=n) v[i]+=x;
   }
}
long querry(long a,long b)
{ long p=a-1; suma1=0; suma2=0;
  while(p>=1) { suma1+=v[p]; p=p-pp[zv[p]]; }
  p=b; 
  while(p>=1) { suma2+=v[p]; p=p-pp[zv[p]]; }
  return suma2-suma1;
}
void cautare(long x)
{ l1=1; l2=n; ok=1; ss=0;
  while(l1<=l2&&ok)
   { mij=(l1+l2)/2; ss=querry(1,mij);
	 if(ss==x) { ok=0; printf("%ld\n",mij); }
	 else if(ss>x) l2=mij-1; else l1=mij+1;
   }
  if(ok) printf("-1\n");
}   
int main()
{ freopen("aib.in","r",stdin); freopen("aib.out","w",stdout);
  scanf("%ld%ld",&n,&m);
  for(i=1;i<=n;i++) 
   {varb=0;x=i;
    while(x%2==0) { varb++; x/=2; } 
    zv[i]=varb;
   }
  pp[0]=1; 
  for(i=1;i<=25;i++)pp[i]=pp[i-1]*2;   
  for(i=1;i<=n;i++) { scanf("%d",&x); add(i,x); }
  for(i=1;i<=m;i++) 
   { scanf("%ld",&l);
     if(l==0) { scanf("%ld%ld",&x,&y); add(x,y); }
	 else if(l==1) { scanf("%ld%ld",&x,&y); printf("%ld\n",querry(x,y)); }
	 else { scanf("%ld",&x); cautare(x);}
   }
  return 0; fclose(stdout);
}