Cod sursa(job #1232452)

Utilizator catalincraciunCraciun Catalin catalincraciun Data 22 septembrie 2014 21:28:14
Problema Arbori indexati binar Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.81 kb
// Craciun Catalin
//  Arbori indexati binar
//   Metode de programare
#include <iostream>
#include <fstream>
#include <cstring>

#define NMax 100005

using namespace std;

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

int n,m;
int A[NMax];

void update(int pos, int x) {

    int c = 0;
    while (pos <= n) {
        A[pos] += x;
        while ( !(pos & (1<<c)) ) c++;
        pos += (1 << c);
        c++;
    }
}

int query(int pos) {

    int sum = 0;
    int c = 0;
    while (pos > 0) {
        sum+=A[pos];
        while ( !(pos & (1<<c)) ) c++;
        pos -= (1<<c);
        c++;
    }

    return sum;
}

int searchForSum(int s) {

    int left = 1, right = n;
    while (left <= right) {
        int mij = (left + right)/2;

        int rez = query(mij);
        if (rez == s) {
            mij--;
            while (query(mij) == s) {
                mij--;
            }
            mij++;

            if (mij > 0)
                return mij;
            return -1;
        } else if (rez < s) {
            left = mij + 1;
        } else if (rez > s) {
            right = mij - 1;
        }
    }

    return -1;
}

int main() {

    memset(A, 0, sizeof(A));
    f>>n>>m;
    for (int i=1;i<=n;i++) {
        int x;
        f>>x;
        update(i,x);
    }

    for (int i=1;i<=m;i++) {
        int type;
        f>>type;
        if (type == 0) {
            int pos, x;
            f>>pos>>x;
            update(pos, x);
        } else if (type == 1) {
            int left, right;
            f>>left>>right;
            g<<query(right)-query(left-1)<<'\n';
        } else if (type == 2) {
            int sum;
            f>>sum;
            g<<searchForSum(sum)<<'\n';
        }
    }

    f.close(); g.close();

    return 0;
}