Cod sursa(job #661335)

Utilizator razvan2006razvan brezulianu razvan2006 Data 14 ianuarie 2012 12:32:16
Problema Arbori indexati binar Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.44 kb
#include <stdio.h>
#define nmax 100010

int AIB[nmax];
int n;

inline int doi_la_k(int x){
   return (((x-1)^x)&x);
}

void actualizeaza(int poz, int val){
    int i;
    for(i=poz;i<=n;i+=doi_la_k(i)){
        AIB[i]+=val;
    }
}

int suma(int poz){
//suma primelor x numere
   int i,s=0;
   for(i=poz;i>0;i-=doi_la_k(i)){
    s+=AIB[i];
   }
   return s;
}

int poz_min(int val){
   int i,pas;
   for(pas=1;pas<n;pas<<=1);
   for(i=0;pas>0;pas>>=1){
      if(i+pas<=n){
         if(AIB[i+pas]<=val){
              i+=pas;
              val-=AIB[i];
              if(!val)return i;
         }
      }
   }
  return -1;
}

int main(){
   int m;
   FILE *fin=fopen("aib.in","r");
   FILE *fout=fopen("aib.out","w");
   fscanf(fin,"%d%d",&n,&m);
   int i;
   int cod,val;
   int a,b;
   int v;   
//citesc vectorul
   for(i=1;i<=n;i++){
      fscanf(fin,"%d",&v);
      actualizeaza(i,v);
   }
   //citesc comenzile
   for(i=0;i<m;i++){
      fscanf(fin,"%d",&cod);
      if(cod<2){
        fscanf(fin,"%d%d",&a,&b);
        if(cod==0){
           //elem de pe poz a i se va adauga valoarea b
           actualizeaza(a,b);
        }else{
           //suma elem v[a]+...+v[b]
           fprintf(fout,"%d\n",suma(b)-suma(a-1));
        }
      }else{
        fscanf(fin,"%d",&val);
        //sa se determine pozitia minima k a.i. suma valorilor pimilor k termeni sa fie exact val
        fprintf(fout,"%d\n",poz_min(val));
      }
   }
   fclose(fin);
   fclose(fout);
return 0;
}