multq3 - Multiples Of 3

Click to show code.


using namespace std;
using iii = array<int, 3>;
const int NMAX = 1e5 + 11;
int n;
int lazy[4 * NMAX];
iii seg[4 * NMAX];
void lazy_propagate(int v, int tl, int tr, int delta)
{
    iii temp(seg[v]);
    int last = (0 - delta % 3 + 3) % 3;
    for (int i = 0; i < 3; ++i)
    {
        seg[v][i] = temp[last];
        last = (last + 1) % 3;
    }
    if (tl != tr)
    {
        lazy[2 * v] += delta;
        lazy[2 * v + 1] += delta;
    }
    lazy[v] = 0;
}
inline iii merge(iii a, iii b)
{
    return {a[0] + b[0], a[1] + b[1], a[2] + b[2]};
}
void update(int v, int tl, int tr, int ql, int qr, int delta)
{
    if (lazy[v] != 0)
        lazy_propagate(v, tl, tr, lazy[v]);
    if (ql > qr)
        return;
    if (ql == tl and qr == tr)
        lazy_propagate(v, tl, tr, delta);
    else
    {
        int tm = (tl + tr) / 2;
        update(2 * v, tl, tm, ql, min(qr, tm), delta);
        update(2 * v + 1, tm + 1, tr, max(tm + 1, ql), qr, delta);
        seg[v] = merge(seg[2 * v], seg[2 * v + 1]);
    }
}
iii query(int v, int tl, int tr, int ql, int qr)
{
    if (lazy[v] != 0)
        lazy_propagate(v, tl, tr, lazy[v]);
    if (ql > qr)
        return {0, 0, 0};
    if (ql == tl and qr == tr)
        return seg[v];
    else
    {
        int tm = (tl + tr) / 2;
        return merge(query(2 * v, tl, tm, ql, min(tm, qr)),
                     query(2 * v + 1, tm + 1, tr, max(tm + 1, ql), qr));
    }
}
void build(int v, int tl, int tr)
{
    if (tl == tr)
        seg[v] = {1, 0, 0};
    else
    {
        int tm = (tl + tr) / 2;
        build(2 * v, tl, tm);
        build(2 * v + 1, tm + 1, tr);
        seg[v] = merge(seg[2 * v], seg[2 * v + 1]);
    }
}
int main(void)
{
    int q, type, ql, qr;
    cin >> n >> q;
    build(1, 0, n - 1);
    while (q--)
    {
        cin >> type >> ql >> qr;
        if (type == 0)
        {
            update(1, 0, n - 1, ql, qr, +1);
        }
        else
        {
            auto [r0, r1, r2] = query(1, 0, n - 1, ql, qr);
            cout << r0 << endl;
        }
    }
    return 0;
}