Cod sursa(job #2754297)

Utilizator icnsrNicula Ionut icnsr Data 25 mai 2021 16:31:35
Problema Datorii Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.31 kb
#include <cstdio>
#include <vector>
#include <climits>
#include <array>

struct Sum
{
        constexpr int operator()(const int a, const int b) const
        {
                return a + b;
        }
};

std::array<int, 4 * 100000> data;

template<typename Cond>
class IntTree
{
public:
        IntTree() = default;

        void insert(const unsigned l, const unsigned r, const int value)
        {
                insert(1, 1, n, l, r, value);
        }

        void query(const unsigned l, const unsigned r, int& res)
        {
                return query(1, 1, n, l, r, res);
        }

        void reset()
        {
                // std::fill(data.begin(), data.end(), 0);
        }

        void init(const unsigned N)
        {
                n = N;
        }

        static unsigned lchild(const unsigned index)
        {
                return index * 2;
        }

        static unsigned rchild(const unsigned index)
        {
                return index * 2 + 1;
        }

        static constexpr Cond cond = Cond{};

private:
        __attribute__((noinline)) void insert(const unsigned index, const unsigned left,
                                              const unsigned right, const unsigned l,
                                              const unsigned r, const int value)
        {
                if(l > right || r < left)
                {
                        return;
                }
                if(left == right)
                {
                        data[index] = value;
                        return;
                }

                const unsigned mij = left + (right - left) / 2;
                const unsigned lc_idx = lchild(index);
                const unsigned rc_idx = rchild(index);

                if(l <= mij)
                {
                        insert(lc_idx, left, mij, l, std::min(mij, r), value);
                }
                if(r > mij)
                {
                        insert(rc_idx, mij + 1, right, std::max(mij + 1, l), r, value);
                }

                data[index] = Cond{}(data[lc_idx], data[rc_idx]);
        }

        __attribute__((noinline)) void query(const unsigned index, const unsigned left,
                                             const unsigned right, const unsigned l,
                                             const unsigned r, int& res)
        {
                if(l > right || r < left)
                {
                        return;
                }
                if(l == left && r == right)
                {
                        res += data[index];
                        return;
                }

                const unsigned mij = left + (right - left) / 2;
                const unsigned lc_idx = lchild(index);
                const unsigned rc_idx = rchild(index);

                if(l <= mij)
                {
                        query(lc_idx, left, mij, l, std::min(mij, r), res);
                }
                if(r > mij)
                {
                        query(rc_idx, mij + 1, right, std::max(mij + 1, l), r, res);
                }
        }

private:
        unsigned n;
};

int main()
{
        FILE* fin = std::fopen("datorii.in", "r");
        FILE* fout = std::fopen("datorii.out", "w");

        std::vector<int> vec;
        IntTree<Sum> itree;
        int N, M;
        std::fscanf(fin, "%d%d", &N, &M);

        vec.reserve(N);
        itree.init(N);
        for(int i = 0; i < N; ++i)
        {
                int value;
                std::fscanf(fin, "%d", &value);

                vec.push_back(value);
                itree.insert(i + 1, i + 1, value);
        }

        for(int i = 0; i < M; ++i)
        {
                int a, b, c;
                std::fscanf(fin, "%d%d%d", &a, &b, &c);

                switch(a)
                {
                case 0:
                {
                        vec[b - 1] -= c;
                        itree.insert(b, b, vec[b - 1]);
                        break;
                }
                case 1:
                {
                        const int x = b;
                        const int y = std::min(x + c, N);

                        int res = 0;
                        itree.query(x, y, res);

                        std::fprintf(fout, "%d\n", res);
                        break;
                }
                }
        }
        // itree.reset();
}