Cod sursa(job #2854349)

Utilizator Casian_doispeChiriac Casian Casian_doispe Data 21 februarie 2022 11:37:10
Problema Arbori indexati binar Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.47 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[100009] ;

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 ;
            }

            if((st + dr) / 2 < 1 || (st + dr) / 2 > n || query(&tree[1], 1, (st + dr) / 2) != b)cout << -1 << "\n" ;
                else cout << (st + dr) / 2 << '\n' ;
        }
    }

    return 0 ;
}
/*



*/