Cod sursa(job #212846)

Utilizator firewizardLucian Dobre firewizard Data 7 octombrie 2008 12:56:40
Problema Arbori indexati binar Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.22 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,c;   
int main()      
{      
       
    freopen("aib.in","r",stdin);      
    freopen("aib.out","w",stdout);      
          
    scanf("%ld%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)      
{      
    c=0;      
    while ( poz<=n ){      
           a[poz]+=val;      
           while(!(poz&(1<<c)))c++;      
           poz += (1<<c);      
           c++;      
           }      
}   
int query(long poz)      
{      
    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)      
{      
    long pos=n+1,m=n;      
    long 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;      
}