Cod sursa(job #3289527)

Utilizator stefan_dore_Stefan Dore stefan_dore_ Data 27 martie 2025 12:31:08
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.12 kb
/**
/// VARIANTA 1
#include <iostream>
#include <fstream>
#include <cmath>
using namespace std;

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

const int NMAX = 100000,
          SQMAX = 1000;
int N, M, nrB, BLOCK_SIZE, V[NMAX+1], SB[NMAX+1];

void citire() {
    f >> N >> M;
    for (int i=0; i<N; i++)
        f >> V[i];
}

void construire() {
    nrB = -1;
    //
    BLOCK_SIZE = (int) sqrt(N);
    //
    for (int i=0; i<N; i++) {
        if (i % BLOCK_SIZE == 0)
            nrB++;
        SB[nrB] += V[i];
    }
}

void update(int poz, int val) {
    int blockNumber = poz / BLOCK_SIZE;
    SB[blockNumber] += val;
    V[poz] += val;
}

int querry1(int st, int dr) {
    int sum = 0;
    //
    while(st <= dr && st % BLOCK_SIZE != 0)
        sum += V[st++];
    //
    while(st + BLOCK_SIZE - 1 <= dr) {
        sum += SB[st/BLOCK_SIZE];
        st += BLOCK_SIZE;
    }
    //
    while(st <= dr)
        sum += V[st++];
    //
    return sum;
}

int querry2(int targetSum) {
    int sum = 0, blockNumber = 0, poz;
    //
    while (sum + SB[blockNumber] < targetSum && blockNumber <= nrB)
        sum += SB[blockNumber++];
    //
    poz = blockNumber * BLOCK_SIZE;
    //
    while (sum + V[poz] < targetSum && poz < N)
        sum += V[poz++];
    //
    if (sum + V[poz] == targetSum) return poz+1;
    return -1;
}

int main()
{
    citire();
    construire();
    int op, a, b;
    for (int i=1; i<=M; i++) {
        f >> op;
        switch(op) {
            case 0:
                f >> a >> b;
                update(a-1, b);
                break;
            case 1:
                f >> a >> b;
                g << querry1(a-1, b-1) << '\n';
                break;
            case 2:
                f >> a;
                g << querry2(a) << '\n';
                break;
        }
    }
    f.close();
    g.close();
    return 0;
}
*/

/// VARIANTA 2
#include <iostream>
#include <fstream>
using namespace std;

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

const int NMAX = 100000;
int N, M, AiB[NMAX+1];

void add(int poz, int val) {
    while (poz <= N) {
        AiB[poz] += val;
        poz += poz & (-poz);
    }
}

int sum(int poz) {
    int s = 0;
    while (poz > 0) {
        s += AiB[poz];
        poz -= poz & (-poz);
    }
    return s;
}

int cautbin(int x) {
    int p = 1, u = N;
    while(p <= u) {
        int m = (p+u) / 2,
            s = sum(m);
        if (s == x)
            return m;
        else if (s > x)
            u = m - 1;
        else
            p = m + 1;
    }
    return -1;
}

int main(){
    int x, y, op;
    f >> N >> M;
    //
    for (int i=1; i<=N; i++) {
        f >> x;
        add(i, x);
    }
    //
    while(M--) {
        f >> op;
        //
        if (op == 0) {
            f >> x >> y;
            add(x, y);
        } else if (op == 1) {
            f >> x >> y;
            g << sum(y) - sum(x-1) << '\n';
        } else {
            f >> x;
            g << cautbin(x) << '\n';
        }
    }
    f.close();
    g.close();
    return 0;
}