Cod sursa(job #2614277)

Utilizator andreiomd1Onut Andrei andreiomd1 Data 11 mai 2020 16:04:27
Problema Arbori indexati binar Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.6 kb
#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int NMAX = 1e5 + 5;

int N, M, A[NMAX];

namespace InParser
{
static const int BSIZE = (1 << 16);
static int pos = BSIZE - 1;

char buff[BSIZE];

static inline char Char ()
{
    ++pos;

    if(pos == BSIZE)
    {
        pos = 0;

        memset(buff, 0, sizeof(buff));
        fread(buff, 1, BSIZE, stdin);
    }

    return buff[pos];
}

static inline int Int ()
{
    int r = 0;

    for( ; ; )
    {
        char Ch = Char();

        if(Ch >= '0' && Ch <= '9')
        {
            r = (int)(Ch - '0');

            break;
        }
    }

    for( ; ; )
    {
        char Ch = Char();

        if(Ch >= '0' && Ch <= '9')
            r = r * 10 + (int)(Ch - '0');
        else
            break;
    }

    return r;
}
};

class FenwickTree
{
    static const int NMAX = 1e5 + 5;
    int A[NMAX];

private:
    inline int UB (int X)
    {
        return (X & (-X));
    }
public:
    inline void Update (int pos, int val)
    {
        for(int i = pos; i <= N; i += UB(i))
            A[i] += val;

        return;
    }

    inline int Query (int pos)
    {
        int r = 0;

        for(int i = pos; i >= 1; i -= UB(i))
            r += A[i];

        return r;
    }
} AIB;

static inline void Read ()
{
    ios_base :: sync_with_stdio(false);
    cin.tie(nullptr);

    freopen("aib.in", "r", stdin);
    freopen("aib.out", "w", stdout);

    N = InParser :: Int();
    M = InParser :: Int();

    for(int i = 1; i <= N; ++i)
        A[i] = InParser :: Int(), AIB.Update(i, A[i]);

    return;
}

static inline void TestCase ()
{
    int Type = InParser :: Int();

    if(Type < 2)
    {
        int a = InParser :: Int(), b = InParser :: Int();

        if(Type == 0)
            AIB.Update(a, b);
        else
            printf("%d\n", AIB.Query(b) - AIB.Query(a - 1));

        return;
    }

    int K = InParser :: Int();

    int Left = 1, Right = N, ans = -1;
    int Sum_for_ans = 0;

    while(Left <= Right)
    {
        int Mid = (Left + Right) >> 1;

        int X = AIB.Query(Mid);

        if(X >= K)
        {
            ans = Mid;
            Sum_for_ans = X;

            Right = Mid - 1;
        }
        else
            Left = Mid + 1;
    }

    if(Sum_for_ans != K)
        ans = -1;

    printf("%d\n", ans);

    return;
}

static inline void Solve ()
{
    while(M--)
        TestCase();

    return;
}

int main()
{
    Read();

    Solve();

    return 0;
}