Cod sursa(job #184983)

Utilizator firewizardLucian Dobre firewizard Data 24 aprilie 2008 17:19:53
Problema Arbori indexati binar Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.97 kb
#include <stdio.h>
#define min(a,b)((a>b)?b:a)
#define FOR(i,s,d) for(i=(s);i<=(d);++i)
void update(long,long);
int search(long);
int query(long);
long a[100005],n,m,i,x,y,k,val,s;
int main()   
{   
    
    freopen("aib.in","r",stdin);   
    freopen("aib.out","w",stdout);   
       
    scanf("l%d%ld",&n,&m);   
    FOR (i,1,n)   {   
        scanf("%ld", &x);   
        update(i,x);   
        }   
       
    FOR(i,1,m){   
        scanf("%ld", &k);     
        if (k<2 ){   
           scanf("%ld%ld", &x, &y);   
           if (k){
              val=query(y)-query(x-1);
              printf("%ld\n",val );
              } 
           else
           update(x,y);   
           }   
        else{   
            scanf("%ld", &x);   
            printf("%ld\n", search(x));
            }   
    }   
}
void update(long poz, long val)   
{   
    int c=0;   
    while ( poz<=n ){   
           a[poz]+=val;   
           while(!(poz&(1<<c)))c++;   
           poz += (1<<c);   
           c++;   
           }   
}
int query(long poz)   
{   
    int c=0,s=0;   
    while ( poz > 0 ){   
          s+= a[poz];   
          while(!(poz&(1<<c)))c++;   
          poz -= (1<<c);   
          c++;   
          }    
    return s;   
}
int search(long S)   
{   
    int pos=n+1,m=n;   
    int st=0,dr=n+1;   
                  
    s=query(m);   
               
    if ( s == S ) pos = n;   
               
    while (m)   
    {   
          m=(st+dr)/2;   
          s=query(m);   
                     
          if(s>S)   
          {   
               if (dr>m)dr=m;   
               m--;   
          }   
          else if (s==S){pos=min(pos,m);dr=m;m--;}   
          else  
          {   
              if (st<m)st=m;   
              m++;   
          }             
          if (m<=st)break;   
          if (m>=dr)break;   
    }   
               
    if (pos==n+1)return -1;   
    return pos;   
}