Mai intai trebuie sa te autentifici.

Cod sursa(job #184989)

Utilizator firewizardLucian Dobre firewizard Data 24 aprilie 2008 17:24:10
Problema Arbori indexati binar Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.94 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(int,int);
int search(int);
int query(int);
int a[100005],n,m,i,x,y,k,val,s,c;
int main()   
{   
    
    freopen("aib.in","r",stdin);   
    freopen("aib.out","w",stdout);   
       
    scanf("%d%d",&n,&m);   
    FOR (i,1,n)   {   
        scanf("%d", &x);   
        update(i,x);   
        }   
       
    FOR(i,1,m){   
        scanf("%d", &k);     
        if (k<2 ){   
           scanf("%d%d", &x, &y);   
           if (k){
              val=query(y)-query(x-1);
              printf("%d\n",val );
              } 
           else
           update(x,y);   
           }   
        else{   
            scanf("%d", &x);   
            printf("%d\n", search(x));
            }   
    }   
}
void update(int poz, int val)   
{   
    c=0;   
    while ( poz<=n ){   
           a[poz]+=val;   
           while(!(poz&(1<<c)))c++;   
           poz += (1<<c);   
           c++;   
           }   
}
int query(int poz)   
{   
    c=0,s=0;   
    while ( poz > 0 ){   
          s+= a[poz];   
          while(!(poz&(1<<c)))c++;   
          poz -= (1<<c);   
          c++;   
          }    
    return s;   
}
int search(int 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;   
}