Cod sursa(job #2854328)

Utilizator Casian_doispeChiriac Casian Casian_doispe Data 21 februarie 2022 11:25:00
Problema Arbori indexati binar Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.59 kb
#include <fstream>
#include <deque>
#include <vector>
#include <bitset>
#include <queue>
#include <algorithm>
#include <cmath>
#include <climits>

#define MOD 104659

using namespace std ;

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

struct nod
{
    int st, dr, mid, val ;

    nod *stfiu, *drfiu ;
};

int n ;

long long query(nod *tatal, int st, int dr)
{
    if(tatal -> st == st && tatal -> dr == dr)
        return tatal -> val ;

    if(dr <= tatal -> mid)
        return query(tatal -> stfiu, st, dr) ;

    if(st >= tatal -> mid + 1)
        return query(tatal -> drfiu, st, dr) ;

    return query(tatal -> stfiu, st, tatal -> mid) + query(tatal -> drfiu, tatal -> mid + 1, dr) ;
}

void update(nod *tatal, int poz, int val)
{
    if(tatal -> st == tatal -> dr)
        {
            tatal -> val += val ;

            return ;
        }

    if(poz <= tatal -> mid)
        update(tatal -> stfiu, poz, val) ;
    else update(tatal -> drfiu, poz, val) ;

    tatal -> val = tatal -> stfiu -> val + tatal -> drfiu -> val ;
}

nod tree[200009] ;

void create(nod *tatal, int st, int dr, int f)
{
    tatal -> st = st ;
    tatal -> dr = dr ;
    tatal -> mid = (st + dr) / 2 ;

    if(st == dr)return ;

    tatal -> stfiu = &tree[2 * f] ;
    tatal -> drfiu = &tree[2 * f + 1] ;

    create(tatal -> stfiu, st, (st + dr) / 2, 2 * f) ;
    create(tatal -> drfiu, (st + dr) / 2 + 1, dr, 2 * f + 1) ;
}

int main()
{
    int q ;

    cin >> n >> q ;

    create(&tree[1], 1, n, 1) ;

    for(int f = 1, a ; f <= n ; f ++)
        cin >> a, update(&tree[1], f, a) ;

    while(q --)
    {
        int a, b, c ;

        cin >> a >> b ;

        if(a == 0)
        {
            cin >> c ;

            update(&tree[1], b, c) ;
        }
        if(a == 1)
        {
            cin >> c ;

            cout << "             " << query(&tree[1], b, c) << '\n' ;
        }
        if(a == 2)
        {
            int st = 1, dr = n ;

            while(st <= dr)
            {
                int mid = (st + dr) / 2 ;

                long long sum = query(&tree[1], 1, mid) ;

                if(sum > b)
                    dr = mid - 1 ;
                else st = mid + 1 ;
            }

            cout << "                " << (st + dr) / 2 << '\n' ;
        }
    }

    return 0 ;
}
/*
10 3
54 36 17 77 21 74 75 0 73 106
1 6 13427
1 4 6289
0 10 10
1 1 370
1 9 33
1 10 12273
0 8 9
0 8 9
1 7 3620
0 5 9
1 10 35
0 8 8
0 2 2
0 5 10
1 3 23314
0 1 5
0 2 9
1 9 33
1 10 9129
0 5 5
1 2 49
*/