Cod sursa(job #993770)

Utilizator alexandru70Ungurianu Alexandru alexandru70 Data 4 septembrie 2013 13:58:10
Problema Arbori indexati binar Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.45 kb
#include <iostream>
#include <fstream>

using namespace std;

ifstream in ("aib.in");
ofstream out ("aib.out");

int v[100001],bit[100001],n;

int RightmostOne(int x) {
	return x&(-x);
}

void BIT_Gen() {
	for(int i = 1; i <= n; ++i) {
		for(int j = i - RightmostOne(i) + 1; j <= i; j++) {
			//cerr << i;
			bit[i]+=v[j];
		}
	}
}

void BIT_Add(int idx, int val) {
	for(int i = idx; i <= n; i+=RightmostOne(i)) {
		//cerr << i;
		bit[i]+=val;
	}
}

int BIT_Compute(int idx) {
	int res = 0;
	for(int i = idx; i > 0; i-=RightmostOne(i)) {
		res+=bit[i];
	}
	return res;
}

int BIT_Find(int val) {
    int step = 1;
    for(;step<n;step<<=1);
    step>>=1;
    int i;
    for(i = step; step!=0;step>>=1) {
        if(i>=n){
            i-=step;
            continue;
        }
        int currV = BIT_Compute(i+1);
        if(currV == val)return i+1;
        if(currV > val)i-=step;
        if(currV < val)i+=step;
    }
    if(BIT_Compute(i+1)==val)return i+1;
    return -1;
}

int main() {
	int m;
	in >> n >> m;
	
	for (int i = 1; i <= n; ++i) {
		in >> v[i];
	}
	BIT_Gen();
	for(int i = 0; i < m; ++i) {
		int c;
		in >> c;
		switch(c) {
			case 0:
				int i,val;
				in >> i >> val;
				BIT_Add(i,val);
				break;
			case 1:
				int st,fn;
				in >> st >> fn;
				out << BIT_Compute(fn)-BIT_Compute(st-1) << '\n';
				break;
            case 2:
                int k;
                in >> k;
                out << BIT_Find(k)<<'\n';
                break;
		}
	}
	return 0;
}