Cod sursa(job #402711)

Utilizator adrianraduleaRadulea Adrian adrianradulea Data 24 februarie 2010 08:42:33
Problema Arbori indexati binar Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.12 kb
#include<stdio.h>
#include<math.h>
FILE *f,*g;
long v[200000],n,suma1,suma2,l1,l2,ok,mij,ss,m,i,a[200000],x,y,l;
int zero(long x)
{ if(x%2==0) return 1+zero(x/2); 
  else return 0; 
}
void add(long i,long x)
{ v[i]+=x;
  while(i<n)
   { i=i+pow(2,zero(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-pow(2,zero(p)); }
  p=b; 
  while(p>=1) { suma2+=v[p]; p=p-pow(2,zero(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++) { scanf("%ld",&a[i]); add(i,a[i]); }
  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);
}