Problem:
Rotating Mass Game
A special feature of the Idua High School Sports Festival is the rotating mass game. In this game, the students rotate and turn their bodies in response to the teacher's command. The students move in unison, which is very cool.
The $N$ students participating in the mass game are numbered from 1 to $N$. At the beginning, the $N$ students are lined up in a row from east to west in order of number from 1 to $N$, and all students stand facing north. The teacher instructs the students how many turns to make. The teacher shouts out three numbers, a, b, and c, and the students from a to b turn their bodies in unison according to the value of c. c is an integer, and if it is positive, the student turns left, and if it is negative, the student turns right, and he/she turns a quarter of a turn for every 1 of the number. For example, if the number is 1, the student turns a quarter turn to the left, if the number is -2, the student turns half a turn to the right, if the number is 4, the student turns one turn to the left, and if the number is -6, the student turns one and a half turns to the right.
The teacher in charge of issuing the instruction received a query from the principal who wanted to know the number of students facing north minus the number of students facing south in a specified range of numbers immediately after the instruction at several points in time. I have the notes of the history of the order at hand, so I should be able to write a program to determine the number of students I want to know at any point in time.
Given the teacher's order and the information about the inquiries from the principal, create a program to find the number of students facing north minus the number of students facing south for each inquiry.
Input
Input is given in the following format.
$N$ $M$
$info_1$
$info_2$
 :
$info_M$
In the first line, the number of students who participated in the mass game $N$ ($1 \leq N \leq 300,000$) and the number of information about the order and query $M$ ($1 \leq M \leq 100,000$) are given. In the following $M$ line, the information $info_i$ about the order and query is given. The information is arranged in chronological order. Each $info_i$ is given in one of the following formats.
1 $a$ $b$ $c$
or
2 $d$ $e$
1
$a$ $b$ $c$ denotes the order that the students from the $a$th to the $b$th should rotate according to the number $c$. However, $1 \leq a \leq b \leq N$ and $-1,000 \leq c \leq 1000$.
2
$d$ $e$ denotes the query of how many students from the $d$th to the $e$th are facing north minus the number of students facing south immediately after the preceding issue. However, $1 \leq d \leq e \leq N$.
One or more pieces of information about the query will be given.
Output
For each query, output the number of students facing north minus the number of students facing south on a single line.
Sample Input and Output
Sample Input
5 5
2 1 5
1 1 2 2
2 1 5
1 2 5 -1
2 1 5
Sample Output
5
1
-1

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, e) for (int i = (int)(s); i < (int)(e); ++i)

template<typename S, auto op, auto e, typename F, auto mapping, auto composition, auto id>
struct LazySegTree {
	int N, height, size;
	vector<S> data;
	vector<F> lazy;
	
	LazySegTree(const vector<S> &v) : N(v.size()) {
		size = 1, height = 0;
		while (size < N) size <<= 1, ++height;
		data = vector<S>(2*size, e());
		lazy = vector<F>(2*size, id());
		for (int i = 0; i < N; ++i) data[size + i] = v[i];
		for (int i = size - 1; i >= 1; --i) update(i);
	}
	
	void update(int i) {
		data[i] = op(data[2*i], data[2*i + 1]);
	}
	
	void all_apply(int i, F f) {
		data[i] = mapping(f, data[i]);
		if (i < size) lazy[i] = composition(f, lazy[i]);
	}
	
	void push(int i) {
		all_apply(2*i, lazy[i]);
		all_apply(2*i + 1, lazy[i]);
		lazy[i] = id();
	}
	
	S prod(int l, int r) {
		if (l == r) return e();
		l += size, r += size;
		for (int i = height; i >= 1; --i) {
			if (((l >> i) << i) != l) push(l >> i);
			if (((r >> i) << i) != r) push((r - 1) >> i);
		}
		S vl = e(), vr = e();
		for (int a = l, b = r; a < b; a >>= 1, b >>= 1) {
			if (a & 1) vl = op(vl, data[a++]);
			if (b & 1) vr = op(data[--b], vr);
		}
		return op(vl, vr);
	}
	
	void apply(int l, int r, F f) {
		if (l == r) return;
		l += size, r += size;
		for (int i = height; i >= 1; --i) {
			if (((l >> i) << i) != l) push(l >> i);
			if (((r >> i) << i) != r) push((r - 1) >> i);
		}
		for (int a = l, b = r; a < b; a >>= 1, b >>= 1) {
			if (a & 1) all_apply(a++, f);
			if (b & 1) all_apply(--b, f);
		}
		for (int i = 1; i <= height; ++i) {
			if (((l >> i) << i) != l) update(l >> i);
			if (((r >> i) << i) != r) update((r - 1) >> i);
		}
	}
};

using S = vector<int>;
using F = ll;

S op(S &a, S &b) {
	S res(4);
	rep(i, 0, 4) res[i] = a[i] + b[i];
	return res;
}
S e() { return {0, 0, 0, 0}; }
S mapping(F f, S &x) {
	f = (f % 4 + 4) % 4;
	S res(4);
	rep(i, 0, 4) res[i] = x[(i + f) % 4];
	return res;
}
F composition(F f, F g) { return f + g; }
F id() { return 0; }

int main() {
	cin.tie(nullptr);
	ios_base::sync_with_stdio(false);
	
	int N, M;
	cin >> N >> M;
	
	vector<S> vec(N);
	rep(i, 0, N) vec[i] = {1, 0, 0, 0};
	LazySegTree<S, op, e, F, mapping, composition, id> seg(vec);
	
	rep(query, 0, M) {
		int ord;
		cin >> ord;
		
		if (ord == 1) {
			int a, b, c;
			cin >> a >> b >> c;
			--a, --b;
			seg.apply(a, b + 1, (ll)c);
		} else {
			int d, e;
			cin >> d >> e;
			--d, --e;
			S res = seg.prod(d, e + 1);
			cout << res[0] - res[2] << '\n';
		}
	}
}
accuracy: 1
time_ms: 340
memory_kb: 85144
final_rank: 19

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;

template <typename T, typename E>
struct LazySegmentTree {
    using F = function<T(T, T)>;
    using G = function<T(T, E)>;
    using H = function<E(E, E)>;

    int n, height;
    vector<T> tree;
    vector<E> lazy;
    const F f;
    const G g;
    const H h;
    const T ti;
    const E ei;

    LazySegmentTree() {}
    LazySegmentTree(F f, G g, H h, T ti, E ei)
        : f(f), g(g), h(h), ti(ti), ei(ei) {}

    void init(int n_) {
        n = 1, height = 0;
        while (n < n_) n *= 2, ++height;

        tree.assign(2 * n, ti);
        lazy.assign(2 * n, ei);
    }

    void build(const vector<T>& v) {
        int n_ = v.size();
        init(n_);
        for (int i = 0; i < n_; ++i) tree[n + i] = v[i];
        for (int i = n - 1; i > 0; i--)
            tree[i] = f(tree[2 * i], tree[2 * i + 1]);
    }

    inline T reflect(int k) {
        return (lazy[k] == ei ? tree[k] : g(tree[k], lazy[k]));
    }

    inline void eval(int k) {
        if (lazy[k] == ei) return;
        lazy[2 * k] = h(lazy[2 * k], lazy[k]);
        lazy[2 * k + 1] = h(lazy[2 * k + 1], lazy[k]);
        tree[k] = reflect(k);
        lazy[k] = ei;
    }

    inline void thrust(int k) {
        for (int i = height; i > 0; --i) eval(k >> i);
    }

    inline void recalc(int k) {
        while (k >>= 1) tree[k] = f(reflect(2 * k), reflect(2 * k + 1));
    }

    void update(int s, int t, const E& x) {
        s += n, t += n;
        thrust(s), thrust(t - 1);
        int l = s, r = t;
        while (l < r) {
            if (l & 1) lazy[l] = h(lazy[l], x), ++l;
            if (r & 1) --r, lazy[r] = h(lazy[r], x);
            l >>= 1, r >>= 1;
        }
        recalc(s), recalc(t - 1);
    }

    T find(int s, int t) {
        s += n, t += n;
        thrust(s), thrust(t - 1);
        int l = s, r = t;
        T ll = ti, rr = ti;
        while (l < r) {
            if (l & 1) ll = f(ll, reflect(l++));
            if (r & 1) rr = f(rr, reflect(--r));
            l >>= 1, r >>= 1;
        }
        return f(ll, rr);
    }

    T at(int i) { return find(i, i + 1); }
};

constexpr int BIG_INT = 1'000'000'100;
constexpr long BIG_LONG = 1'000'000'000'000'000'100;

struct S {
    int a, b, c, d;
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    auto f = [](S a, S b) {
        return S{a.a + b.a, a.b + b.b, a.c + b.c, a.d + b.d};
    };
    auto g = [](S a, int x) {
        for (int i = 0; i < x; i++) {
            a = S{a.b, a.c, a.d, a.a};
        }
        return a;
    };
    auto h = [](int x, int y) { return (x + y) % 4; };
    LazySegmentTree<S, int> sg(f, g, h, S{0, 0, 0, 0}, 0);

    int n, m;
    cin >> n >> m;
    sg.build(vector(n, S{1, 0, 0, 0}));
    while (m--) {
        int qn;
        cin >> qn;
        if (qn == 1) {
            int a, b, c;
            cin >> a >> b >> c;
            a--;
            sg.update(a, b, (c + 4000) % 4);
        } else {
            int d, e;
            cin >> d >> e;
            d--;
            auto [A, B, C, D] = sg.find(d, e);
            cout << A - C << '\n';
        }
    }
}
accuracy: 1
time_ms: 100
memory_kb: 28320
final_rank: 9

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;

#ifndef ATCODER_LAZYSEGTREE_HPP
#define ATCODER_LAZYSEGTREE_HPP 1

#include <algorithm>
#include <cassert>
#include <functional>
#include <vector>

#ifndef ATCODER_INTERNAL_BITOP_HPP
#define ATCODER_INTERNAL_BITOP_HPP 1

#ifdef _MSC_VER
#include <intrin.h>
#endif

#if __cplusplus >= 202002L
#include <bit>
#endif

namespace atcoder {

namespace internal {

#if __cplusplus >= 202002L

using std::bit_ceil;

#else

// @return same with std::bit::bit_ceil
unsigned int bit_ceil(unsigned int n) {
    unsigned int x = 1;
    while (x < (unsigned int)(n)) x *= 2;
    return x;
}

#endif

// @param n `1 <= n`
// @return same with std::bit::countr_zero
int countr_zero(unsigned int n) {
#ifdef _MSC_VER
    unsigned long index;
    _BitScanForward(&index, n);
    return index;
#else
    return __builtin_ctz(n);
#endif
}

// @param n `1 <= n`
// @return same with std::bit::countr_zero
constexpr int countr_zero_constexpr(unsigned int n) {
    int x = 0;
    while (!(n & (1 << x))) x++;
    return x;
}

}  // namespace internal

}  // namespace atcoder

#endif  // ATCODER_INTERNAL_BITOP_HPP

namespace atcoder {

#if __cplusplus >= 201703L

template <class S, auto op, auto e, class F, auto mapping, auto composition,
          auto id>
struct lazy_segtree {
    static_assert(std::is_convertible_v<decltype(op), std::function<S(S, S)>>,
                  "op must work as S(S, S)");
    static_assert(std::is_convertible_v<decltype(e), std::function<S()>>,
                  "e must work as S()");
    static_assert(
        std::is_convertible_v<decltype(mapping), std::function<S(F, S)>>,
        "mapping must work as S(F, S)");
    static_assert(
        std::is_convertible_v<decltype(composition), std::function<F(F, F)>>,
        "composition must work as F(F, F)");
    static_assert(std::is_convertible_v<decltype(id), std::function<F()>>,
                  "id must work as F()");

#else

template <class S, S (*op)(S, S), S (*e)(), class F, S (*mapping)(F, S),
          F (*composition)(F, F), F (*id)()>
struct lazy_segtree {

#endif

   public:
    lazy_segtree() : lazy_segtree(0) {}
    explicit lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {}
    explicit lazy_segtree(const std::vector<S>& v) : _n(int(v.size())) {
        size = (int)internal::bit_ceil((unsigned int)(_n));
        log = internal::countr_zero((unsigned int)size);
        d = std::vector<S>(2 * size, e());
        lz = std::vector<F>(size, id());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) {
            update(i);
        }
    }

    void set(int p, S x) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        return d[p];
    }

    S prod(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return e();

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }

        S sml = e(), smr = e();
        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }

        return op(sml, smr);
    }

    S all_prod() { return d[1]; }

    void apply(int p, F f) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = mapping(f, d[p]);
        for (int i = 1; i <= log; i++) update(p >> i);
    }
    void apply(int l, int r, F f) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return;

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }

        {
            int l2 = l, r2 = r;
            while (l < r) {
                if (l & 1) all_apply(l++, f);
                if (r & 1) all_apply(--r, f);
                l >>= 1;
                r >>= 1;
            }
            l = l2;
            r = r2;
        }

        for (int i = 1; i <= log; i++) {
            if (((l >> i) << i) != l) update(l >> i);
            if (((r >> i) << i) != r) update((r - 1) >> i);
        }
    }

    template <bool (*g)(S)>
    int max_right(int l) {
        return max_right(l, [](S x) { return g(x); });
    }
    template <class G>
    int max_right(int l, G g) {
        assert(0 <= l && l <= _n);
        assert(g(e()));
        if (l == _n) return _n;
        l += size;
        for (int i = log; i >= 1; i--) push(l >> i);
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!g(op(sm, d[l]))) {
                while (l < size) {
                    push(l);
                    l = (2 * l);
                    if (g(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, d[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }

    template <bool (*g)(S)>
    int min_left(int r) {
        return min_left(r, [](S x) { return g(x); });
    }
    template <class G>
    int min_left(int r, G g) {
        assert(0 <= r && r <= _n);
        assert(g(e()));
        if (r == 0) return 0;
        r += size;
        for (int i = log; i >= 1; i--) push((r - 1) >> i);
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!g(op(d[r], sm))) {
                while (r < size) {
                    push(r);
                    r = (2 * r + 1);
                    if (g(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

   private:
    int _n, size, log;
    std::vector<S> d;
    std::vector<F> lz;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
    void all_apply(int k, F f) {
        d[k] = mapping(f, d[k]);
        if (k < size) lz[k] = composition(f, lz[k]);
    }
    void push(int k) {
        all_apply(2 * k, lz[k]);
        all_apply(2 * k + 1, lz[k]);
        lz[k] = id();
    }
};

}  // namespace atcoder

#endif  // ATCODER_LAZYSEGTREE_HPP

constexpr int BIG_INT = 1'000'000'100;
constexpr long BIG_LONG = 1'000'000'000'000'000'100;

struct S {
    int a, b, c, d;
};

S op(S a, S b) { return S{a.a + b.a, a.b + b.b, a.c + b.c, a.d + b.d}; }
S e() { return {0, 0, 0, 0}; }
using F = int;
S mapping(F f, S x) {
    for (int i = 0; i < f; i++) {
        x = {x.b, x.c, x.d, x.a};
    }
    return x;
}
F composition(F f, F g) { return (f + g) % 4; }
F id() { return 0; }

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m;
    cin >> n >> m;
    atcoder::lazy_segtree<S, op, e, F, mapping, composition, id> sg(
        vector(n, S{1, 0, 0, 0}));
    while (m--) {
        int qn;
        cin >> qn;
        if (qn == 1) {
            int a, b, c;
            cin >> a >> b >> c;
            a--;
            sg.apply(a, b, (c + 4000) % 4);
        } else {
            int d, e;
            cin >> d >> e;
            d--;
            auto [A, B, C, D] = sg.prod(d, e);
            cout << A - C << '\n';
        }
    }
}
accuracy: 1
time_ms: 70
memory_kb: 26276
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define ll long long
const long long mod=998244353;
const long long hmod=46216567629137;
struct S{
    int n,e,s,w;
};
using F=ll;
const F ID=0;
S e(){//Sの単位元
    S res;
    res.n=0;
    res.e=0;
    res.s=0;
    res.w=0;
    return res;
}
F id(){//Fの単位元
    return ID;
}
S op(S a,S b){//Sの結合
    S res;
    res.n=a.n+b.n;
    res.e=a.e+b.e;
    res.s=a.s+b.s;
    res.w=a.w+b.w;
    return res;
}
S mapping(F f,S x){//Sに遅延伝播をかける
    f%=4;
    if(f<0) f+=4;
    S res;
    if(f==0){
        res=x;
    }
    if(f==1){
        res.n=x.e;
        res.e=x.s;
        res.s=x.w;
        res.w=x.n;
    }
    if(f==2){
        res.n=x.s;
        res.e=x.w;
        res.s=x.n;
        res.w=x.e;
    }
    if(f==3){
        res.n=x.w;
        res.e=x.n;
        res.s=x.e;
        res.w=x.s;
    }
    return res;
}
F composition(F f,F g){//lazy同士の合成(gにfの操作をする)
    F res=(f+g)%4;
    if(res<0) res+=4;
    return res;
}
class lazysegtree{
    public:
    S dat[1200009];
    F lazy[1200009];
    ll siz;
    lazysegtree(ll N){
        siz=1;
        while(siz<N) siz*=2;
        for(ll i=1;i<siz*2;i++){
            dat[i]=e();
            lazy[i]=id();
        }
    }

    S prod(int l,int r,int a,int b,int u){
        if(b<=l || r<=a)return e();
        if(l<=a && b<=r){
            return dat[u];
        }
        int m=(a+b)/2;
        S L=mapping(lazy[u],prod(l,r,a,m,u*2));
        S R=mapping(lazy[u],prod(l,r,m,b,u*2+1));
        return op(L,R);
    }
    S prod(int l,int r){
        return prod(l,r,1,siz+1,1);
    }
    S all_prod(){
        return prod(1,siz+1,1,siz+1,1);
    }
    S get(int p){
        return prod(p,p+1,1,siz+1,1);
    }
    void apply(int l,int r,int a,int b,int u,F f){
        if(b<=l || r<=a) return;
        if(l<=a && b<=r){
            lazy[u]=composition(f,lazy[u]);
            dat[u]=mapping(f,dat[u]);
            return;
        }
        lazy[u*2]=composition(lazy[u],lazy[u*2]);
        lazy[u*2+1]=composition(lazy[u],lazy[u*2+1]);
        dat[u*2]=mapping(lazy[u],dat[u*2]);
        dat[u*2+1]=mapping(lazy[u],dat[u*2+1]);
        lazy[u]=id();
        int m=(a+b)/2;
        apply(l,r,a,m,u*2,f);
        apply(l,r,m,b,u*2+1,f);
        S L=mapping(lazy[u],dat[u*2]);
        S R=mapping(lazy[u],dat[u*2+1]);
        dat[u]=op(L,R);
        return;
    }

    void apply(int p,F f){
        apply(p,p+1,1,siz+1,1,f);
    }
    void apply(int l,int r,F f){
        apply(l,r,1,siz+1,1,f);
    }
    void set(int p,S x){
        p=p+siz-1;
        dat[p]=x;
        while(p>=2){
            p/=2;
            dat[p]=op(dat[p*2],dat[p*2+1]);
        }
        return;
    }
};
int main(){
    cin.tie(0)->sync_with_stdio(0);
    cout.tie(0);
    int N,M;
    cin>>N>>M;
    lazysegtree seg(N);
    for(int i=1;i<=N;i++){
        S d={1,0,0,0};
        seg.set(i,d);
    }
    for(int z=1;z<=M;z++){
        int query;
        cin>>query;
        if(query==1){
            int a,b,c;
            cin>>a>>b>>c;
            c%=4;
            if(c<0) c+=4;
            seg.apply(a,b+1,c);
        }
        if(query==2){
            int d,e;
            cin>>d>>e;
            S dat=seg.prod(d,e+1);
            cout<<dat.n-dat.s<<"\n";
        }
    }
}
accuracy: 1
time_ms: 100
memory_kb: 31120
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
// #include<atcoder/all>
// using mint = atcoder::modint998244353;
using ld = long double;
#define fi first
#define se second
#define all(x) x.begin(),x.end()
#define rep(i,n) for(int i=0;i<(int)(n);++i)
template<typename T>bool chmin(T&a,T b){return b<a?(a=b,1):0;}
template<typename T>bool chmax(T&a,T b){return b>a?(a=b,1):0;}


template <class S, 
          S (*op)(S, S), 
          S (*e)(), 
          class F, 
          S (*mapping)(F, S), 
          F (*composition)(F, F), 
          F (*id)()>
struct lazy_segtree {
  public:
    lazy_segtree() : lazy_segtree(0) {}
    explicit lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {}
    explicit lazy_segtree(const std::vector<S>& v) : _n(int(v.size())) {
        size = (int)bit_ceil(_n);
        log = countr_zero(size);
        d = std::vector<S>(2 * size, e());
        lz = std::vector<F>(size, id());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) {
            update(i);
        }
    }

    void set(int p, S x) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        return d[p];
    }

    S prod(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return e();

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }

        S sml = e(), smr = e();
        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }

        return op(sml, smr);
    }

    S all_prod() { return d[1]; }

    void apply(int p, F f) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = mapping(f, d[p]);
        for (int i = 1; i <= log; i++) update(p >> i);
    }
    void apply(int l, int r, F f) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return;

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }

        {
            int l2 = l, r2 = r;
            while (l < r) {
                if (l & 1) all_apply(l++, f);
                if (r & 1) all_apply(--r, f);
                l >>= 1;
                r >>= 1;
            }
            l = l2;
            r = r2;
        }

        for (int i = 1; i <= log; i++) {
            if (((l >> i) << i) != l) update(l >> i);
            if (((r >> i) << i) != r) update((r - 1) >> i);
        }
    }

    template <bool (*g)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return g(x); });
    }
    template <class G> int max_right(int l, G g) {
        assert(0 <= l && l <= _n);
        assert(g(e()));
        if (l == _n) return _n;
        l += size;
        for (int i = log; i >= 1; i--) push(l >> i);
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!g(op(sm, d[l]))) {
                while (l < size) {
                    push(l);
                    l = (2 * l);
                    if (g(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, d[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }

    template <bool (*g)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return g(x); });
    }
    template <class G> int min_left(int r, G g) {
        assert(0 <= r && r <= _n);
        assert(g(e()));
        if (r == 0) return 0;
        r += size;
        for (int i = log; i >= 1; i--) push((r - 1) >> i);
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!g(op(d[r], sm))) {
                while (r < size) {
                    push(r);
                    r = (2 * r + 1);
                    if (g(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

  private:
    int _n, size, log;
    std::vector<S> d;
    std::vector<F> lz;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
    void all_apply(int k, F f) {
        d[k] = mapping(f, d[k]);
        if (k < size) lz[k] = composition(f, lz[k]);
    }
    void push(int k) {
        all_apply(2 * k, lz[k]);
        all_apply(2 * k + 1, lz[k]);
        lz[k] = id();
    }

    static int bit_ceil(int x) {
        return 1 << (32 - __builtin_clz(x - 1));
    }

    static int countr_zero(int x) {
        return __builtin_ctz(x);
    }
};


using S=array<int,4>;
S op(S l, S r){
    rep(i,4) l[i]+=r[i];
    return l;
}
S e(){return {0,0,0,0};}
using F=int;
S mapping(F f, S s){
    S ret;
    rep(i,4) ret[(i+f)%4]=s[i];
    return ret;
}
F composition(F f, F g){
    return (f+g)%4;
}
F id(){return 0;}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    
    int N,M;
    cin>>N>>M;
    lazy_segtree<S,op,e,F,mapping,composition,id> seg(N);
    rep(i,N) seg.set(i, {1,0,0,0});
    rep(i,M){
        int t;
        cin>>t;
        if(t==1){
            int a,b,c;
            cin>>a>>b>>c;
            a--;
            c=(c+1000)%4;
            seg.apply(a,b,c);
        }
        else{
            int d,c;
            cin>>d>>c;
            d--;
            S s=seg.prod(d,c);
            cout<<s[0]-s[2]<<"\n";
        }
    }
}
accuracy: 1
time_ms: 220
memory_kb: 26504
final_rank: 15

code_snippet: //#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")


#ifndef ONLINE_JUDGE
#define _GLIBCXX_DEBUG
#endif


#include <bits/stdc++.h>
using namespace std;


#define rep(i, N) for (int i = 0; i < N; i++)
#define repn(i, n, N) for (int i = n; i < N; i++)
#define fore(i, x) for(auto i : x)
#define rep1(i, N) for(int i = 1; i <= N; i++)
#define ll long long
#define ull unsigned long long

template<class T> inline bool chmin(T& a, T b){ if(a > b){ a = b; return 1;} return 0;}
template<class T> inline bool chmax(T& a, T b){ if (a < b){a = b; return 1;} return 0;}

const long long INF_LL = 1LL << 60;
const int INF_I = 1 << 30;

int dy[4] = {0, 1, 0, -1};
int dx[4] = {1, 0, -1, 0};

int RandInt(int a, int b){
    return a + rand() % (b - a + 1);
}

double RandDouble(){
    return 1.0 * rand() / RAND_MAX;
}

void overflow(ll a) {if(a < 0) throw;}


#if __cplusplus >= 201703L

template <class S,
          auto op,
          auto e,
          class F,
          auto mapping,
          auto composition,
          auto id>
struct lazy_segtree {
    static_assert(std::is_convertible_v<decltype(op), std::function<S(S, S)>>,
                  "op must work as S(S, S)");
    static_assert(std::is_convertible_v<decltype(e), std::function<S()>>,
                  "e must work as S()");
    static_assert(
        std::is_convertible_v<decltype(mapping), std::function<S(F, S)>>,
        "mapping must work as S(F, S)");
    static_assert(
        std::is_convertible_v<decltype(composition), std::function<F(F, F)>>,
        "composition must work as F(F, F)");
    static_assert(std::is_convertible_v<decltype(id), std::function<F()>>,
                  "id must work as F()");

#else

template <class S,
          S (*op)(S, S),
          S (*e)(),
          class F,
          S (*mapping)(F, S),
          F (*composition)(F, F),
          F (*id)()>
struct lazy_segtree {

#endif

  public:
    lazy_segtree() : lazy_segtree(0) {}
    explicit lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {}
    explicit lazy_segtree(const std::vector<S>& v) : _n(int(v.size())) {
        size = (int)bit_ceil((unsigned int)(_n));
        log = countr_zero((unsigned int)size);
        d = std::vector<S>(2 * size, e());
        lz = std::vector<F>(size, id());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) {
            update(i);
        }
    }

    void set(int p, S x) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        return d[p];
    }

    S prod(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return e();

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }

        S sml = e(), smr = e();
        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }

        return op(sml, smr);
    }

    S all_prod() { return d[1]; }

    void apply(int p, F f) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = mapping(f, d[p]);
        for (int i = 1; i <= log; i++) update(p >> i);
    }
    void apply(int l, int r, F f) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return;

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }

        {
            int l2 = l, r2 = r;
            while (l < r) {
                if (l & 1) all_apply(l++, f);
                if (r & 1) all_apply(--r, f);
                l >>= 1;
                r >>= 1;
            }
            l = l2;
            r = r2;
        }

        for (int i = 1; i <= log; i++) {
            if (((l >> i) << i) != l) update(l >> i);
            if (((r >> i) << i) != r) update((r - 1) >> i);
        }
    }

    template <bool (*g)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return g(x); });
    }
    template <class G> int max_right(int l, G g) {
        assert(0 <= l && l <= _n);
        assert(g(e()));
        if (l == _n) return _n;
        l += size;
        for (int i = log; i >= 1; i--) push(l >> i);
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!g(op(sm, d[l]))) {
                while (l < size) {
                    push(l);
                    l = (2 * l);
                    if (g(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, d[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }

    template <bool (*g)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return g(x); });
    }
    template <class G> int min_left(int r, G g) {
        assert(0 <= r && r <= _n);
        assert(g(e()));
        if (r == 0) return 0;
        r += size;
        for (int i = log; i >= 1; i--) push((r - 1) >> i);
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!g(op(d[r], sm))) {
                while (r < size) {
                    push(r);
                    r = (2 * r + 1);
                    if (g(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

  private:
    int _n, size, log;
    std::vector<S> d;
    std::vector<F> lz;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
    void all_apply(int k, F f) {
        d[k] = mapping(f, d[k]);
        if (k < size) lz[k] = composition(f, lz[k]);
    }
    void push(int k) {
        all_apply(2 * k, lz[k]);
        all_apply(2 * k + 1, lz[k]);
        lz[k] = id();
    }
};


struct S{
    int d[4];
};

using F = int;

S op(S a, S b){
    S s;
    s.d[0] = a.d[0] + b.d[0];
    s.d[1] = a.d[1] + b.d[1];
    s.d[2] = a.d[2] + b.d[2];
    s.d[3] = a.d[3] + b.d[3];
    return s;
}

S e(){
    S s;
    s.d[0] = 0;
    s.d[1] = 0;
    s.d[2] = 0;
    s.d[3] = 0;
    return s;
}

S mapping(F f, S x){
    S s;
    for(int i = 0; i < 4; i++){
        s.d[(i + f + 4000) % 4] = x.d[i];
    }

    return s;
}

F composition(F f, F g){
    return (f + g + 400000) % 4;
}

F id(){return 0;}


int main(){
    int N, M; cin >> N >> M;

    S init = e();
    init.d[0] = 1;

    vector<S> v(N, init);

    lazy_segtree<S, op, e, F, mapping, composition, id> seg(v);

    for(;M--;){
        int q; cin >> q;

        if(q == 1){
            int a, b, c; cin >> a >> b >> c;
            a--;
            seg.apply(a, b, c);
        }
        if(q == 2){
            int d, e; cin >> d >> e;
            d--;

            S x = seg.prod(d, e);
            cout << x.d[0] - x.d[2] << endl;
        }
    }
}
accuracy: 1
time_ms: 150
memory_kb: 26480
final_rank: 12

code_snippet: // AOJ #464
// Rotating Mass Game 2025.2.9
 
#include <bits/stdc++.h>
using namespace std;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {  // 整数の入力
	int n = 0, c = gc();
	if (c == '-') {	c = gc();
		do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
		return -n;
	}
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(int n) { // 整数の表示（出力）
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

const int MAXN = 300000;
const int SEG_SIZE = 4 * MAXN;

struct Node { int cnt[4]; };

Node seg[SEG_SIZE];
int lazy[SEG_SIZE];

void build(int idx, int l, int r) {
    if(l == r) {
        seg[idx].cnt[0] = 1;
        seg[idx].cnt[1] = 0;
        seg[idx].cnt[2] = 0;
        seg[idx].cnt[3] = 0;
        lazy[idx] = 0;
        return;
    }
    int mid = (l + r) / 2;
    build(idx * 2, l, mid);
    build(idx * 2 + 1, mid + 1, r);
    lazy[idx] = 0;
    for(int i = 0; i < 4; i++){
        seg[idx].cnt[i] = seg[idx * 2].cnt[i] + seg[idx * 2 + 1].cnt[i];
    }
}

void apply(int idx, int d) {
    if(d == 0) return;
    int tmp[4];
    for (int i = 0; i < 4; i++) {
        tmp[i] = seg[idx].cnt[i];
    }
    for (int i = 0; i < 4; i++){
        seg[idx].cnt[i] = tmp[((i - d) % 4 + 4) % 4];
    }
    lazy[idx] = (lazy[idx] + d) % 4;
}

void pushDown(int idx) {
    if(lazy[idx] != 0) {
        int d = lazy[idx];
        apply(idx * 2, d);
        apply(idx * 2 + 1, d);
        lazy[idx] = 0;
    }
}

void update(int idx, int l, int r, int ql, int qr, int d) {
    if(ql <= l && r <= qr) {
        apply(idx, d);
        return;
    }
    pushDown(idx);
    int mid = (l + r) / 2;
    if(ql <= mid)
        update(idx * 2, l, mid, ql, qr, d);
    if(qr > mid)
        update(idx * 2 + 1, mid + 1, r, ql, qr, d);
    for (int i = 0; i < 4; i++){
        seg[idx].cnt[i] = seg[idx * 2].cnt[i] + seg[idx * 2 + 1].cnt[i];
    }
}

Node query(int idx, int l, int r, int ql, int qr) {
    if(ql <= l && r <= qr) return seg[idx];
    pushDown(idx);
    int mid = (l + r) / 2;
    Node res;
    for (int i = 0; i < 4; i++) res.cnt[i] = 0;
    if(ql <= mid) {
        Node leftRes = query(idx * 2, l, mid, ql, qr);
        for (int i = 0; i < 4; i++) res.cnt[i] += leftRes.cnt[i];
    }
    if(qr > mid) {
        Node rightRes = query(idx * 2 + 1, mid + 1, r, ql, qr);
        for (int i = 0; i < 4; i++) res.cnt[i] += rightRes.cnt[i];
    }
    return res;
}
 
int main(){
    int N = Cin(), M = Cin();

    build(1, 1, N);
    
    for (int i = 0; i < M; i++){
        int type = Cin();
        if(type == 1) {
            int a = Cin(), b = Cin(), c = Cin();
            int d = ((c % 4) + 4) % 4;
            update(1, 1, N, a, b, d);
        } else {
            int d = Cin(), e = Cin();
            Node ans = query(1, 1, N, d, e);
            int result = ans.cnt[0] - ans.cnt[2];
            Cout(result);
        }
    }
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 25868
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main()
{
	int n,m;
	cin >> n >> m;
	vector<int> a(n,0);
	int q = 1;
	while(q * q < n) q++;
	vector<vector<int>> cou(q,vector<int>(4,0));
	vector<int> sum(q,0);
	for(int i = 0;i < n;i++){
		cou[i / q][0]++;
	}
	for(int i = 0;i < m;i++){
		int p;
		cin >> p;
		if(p == 1){
			int l,r,c;
			cin >> l >> r >> c;
			l--;r--;
			c += 4000;
			c %= 4;
			for(int j = 0;j < q;j++){
				int left = j * q,right = j * q + q - 1;
				if(right < l || r < left) continue;
				if(l <= left && right <= r){
					sum[j] += c;
					vector<int> nex(4,0);
					for(int k = 0;k < 4;k++){
						nex[(k + c) % 4] = cou[j][k];
					}
					swap(cou[j],nex);
				}else{
					for(int k = left;k <= right;k++){
						if(k >= n) break;
						a[k] = (a[k] + sum[j]) % 4;
						cou[j][a[k]]--;
						if(l <= k && k <= r){
							a[k] = (a[k] + c) % 4;
						}
						cou[j][a[k]]++;
					}
					sum[j] = 0;
				}
			}
		}else{
			int l,r;
			cin >> l >> r;
			l--;r--;
			int ans = 0;
			for(int j = 0;j < q;j++){
				int left = j * q,right = j * q + q - 1;
				if(right < l || r < left) continue;
				if(l <= left && right <= r){
					ans += cou[j][0];
					ans -= cou[j][2];
				}else{
					for(int k = left;k <= right;k++){
						if(k >= n) break;
						a[k] = (a[k] + sum[j]) % 4;
						if(l <= k && k <= r){
							if(a[k] == 0){
								ans++;
							}
							if(a[k] == 2){
								ans--;
							}
						}
					}
					sum[j] = 0;
				}
			}
			cout << ans << endl;
		}
	}
}
accuracy: 1
time_ms: 900
memory_kb: 4440
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T> using V = vector<T>;
#define REP(i, n) for (ll i = 0; i < (n); i++)
#define REP2(i, a, b) for (ll i = (a); i < (b); i++)

template <class S,
          auto op,
          auto e,
          class F,
          auto mapping,
          auto composition,
          auto id>
struct lazy_segtree {
  public:
    lazy_segtree() : lazy_segtree(0) {}
    explicit lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {}
    explicit lazy_segtree(const std::vector<S>& v) : _n(int(v.size())) {
		{
			unsigned int x = 1;
			while (x < (unsigned int)(_n)) x *= 2;
			size = (int)x;
		}
        log = __builtin_ctz((unsigned int)size);
        d = std::vector<S>(2 * size, e());
        lz = std::vector<F>(size, id());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) {
            update(i);
        }
    }

    void set(int p, S x) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        return d[p];
    }

    S prod(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return e();

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }

        S sml = e(), smr = e();
        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }

        return op(sml, smr);
    }

    S all_prod() { return d[1]; }

    void apply(int p, F f) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = mapping(f, d[p]);
        for (int i = 1; i <= log; i++) update(p >> i);
    }
    void apply(int l, int r, F f) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return;

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }

        {
            int l2 = l, r2 = r;
            while (l < r) {
                if (l & 1) all_apply(l++, f);
                if (r & 1) all_apply(--r, f);
                l >>= 1;
                r >>= 1;
            }
            l = l2;
            r = r2;
        }

        for (int i = 1; i <= log; i++) {
            if (((l >> i) << i) != l) update(l >> i);
            if (((r >> i) << i) != r) update((r - 1) >> i);
        }
    }
  private:
    int _n, size, log;
    std::vector<S> d;
    std::vector<F> lz;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
    void all_apply(int k, F f) {
        d[k] = mapping(f, d[k]);
        if (k < size) lz[k] = composition(f, lz[k]);
    }
    void push(int k) {
        all_apply(2 * k, lz[k]);
        all_apply(2 * k + 1, lz[k]);
        lz[k] = id();
    }
};

using S = array<int, 4>;
using F = int;
S op(S a, S b) {
	return S{a[0] + b[0], \
		a[1] + b[1], \
		a[2] + b[2], \
		a[3] + b[3]};
}
S e() { return S{0, 0, 0, 0}; }
S mapping(F f, S a) {
	return S{a[(f + 0) % 4], a[(f + 1) % 4], a[(f + 2) % 4], a[(f + 3) % 4]};
}
F composition(F f, F g) {
	return f + g;
}
F id() { return 0; }

int main()
{
	int n, m; cin >> n >> m;
	lazy_segtree<S, op, e, F, mapping, composition, id> seg(V<S>(n, array<int, 4>{1, 0, 0, 0}));
	REP(_, m) {
		int t; cin >> t;
		if (t == 1) {
			int a, b, c; cin >> a >> b >> c;
			seg.apply(a - 1, b, (c % 4 + 4) % 4);
		} else {
			int d, e; cin >> d >> e;
			auto res = seg.prod(d - 1, e);
			cout << res[0] - res[2] << endl;
		}
	}
}
accuracy: 1
time_ms: 130
memory_kb: 26304
final_rank: 10

code_snippet: #include <bits/stdc++.h>

namespace zawa {

using u32 = std::uint32_t;
using usize = std::size_t;

template <class Structure>
class LazySegmentTree {
public:
    using VM = typename Structure::ValueMonoid;
    using OM = typename Structure::OperatorMonoid;
    using Value = typename VM::Element;
    using Operator = typename OM::Element;
private:
    static constexpr u32 parent(u32 v) noexcept {
        return v >> 1;
    }
    static constexpr u32 left(u32 v) noexcept {
        return v << 1 | 0;
    }
    static constexpr u32 right(u32 v) noexcept {
        return v << 1 | 1;
    }
    static constexpr u32 depth(u32 v) noexcept {
        return 31u - __builtin_clz(v);
    }
    static constexpr u32 trailingZeros(u32 v) noexcept {
        return __builtin_ctz(v);
    }

    struct Node {
        Value v_{VM::identity()};
        Operator o_{OM::identity()};
        Node() = default;
        Node(const Value& v, const Operator& o) : v_{v}, o_{o} {}
    };

    usize n_{};
    std::vector<Node> dat_;

    static Value action(const Node& node) {
        return Structure::mapping(node.v_, node.o_);
    }

    void propagate(u32 v) {
        dat_[left(v)].o_ = OM::operation(dat_[left(v)].o_, dat_[v].o_);
        dat_[right(v)].o_ = OM::operation(dat_[right(v)].o_, dat_[v].o_);
        dat_[v].o_ = OM::identity();
    }

    void propagateAncestor(u32 v) {
        u32 dep{depth(v)};
        u32 zeros{trailingZeros(v)};
        for (u32 d{dep} ; d != zeros ; d--) {
            propagate(v >> d);
        }
    }

    void recalc(u32 v) {
        dat_[v].v_ = VM::operation(action(dat_[left(v)]), action(dat_[right(v)]));
    }

    void recalcAncestor(u32 v) {
        v >>= trailingZeros(v);
        for (v = parent(v) ; v ; v = parent(v)) {
            recalc(v);
        }
    }

    template <class InputIterator>
    void datInit(InputIterator first) {
        auto it{first};
        for (u32 i{} ; i < n_ ; i++) {
            dat_[i + n_].v_ = *it;
            it++;
        }
        for (u32 i{static_cast<u32>(n_)} ; --i ; ) {
            dat_[i].v_ = VM::operation(dat_[left(i)].v_, dat_[right(i)].v_);
        }
    }

public:
    LazySegmentTree() = default;
    LazySegmentTree(usize n) : n_{n}, dat_((n << 1)) {
        assert(n_);
    }
    LazySegmentTree(const std::vector<Value>& a) : n_{a.size()}, dat_((a.size() << 1)) {
        assert(!a.empty());
        datInit(a.begin());
    }
    usize size() const noexcept {
        return n_;
    }
    void operation(u32 L, u32 R, const Operator& o) {
        assert(L <= n_ and R <= n_);
        L += size();
        R += size();
        propagateAncestor(L);
        propagateAncestor(R);
        for (u32 l = L, r = R ; l < r ; l = parent(l), r = parent(r)) {
            if (l & 1) {
                dat_[l].o_ = OM::operation(dat_[l].o_, o);
                l++;
            }
            if (r & 1) {
                r--;
                dat_[r].o_ = OM::operation(dat_[r].o_, o);
            }
        }
        recalcAncestor(L);
        recalcAncestor(R);
    }
    Value product(u32 L, u32 R) {
        assert(L <= n_ and R <= n_);
        L += size();
        R += size();
        propagateAncestor(L);
        propagateAncestor(R);
        recalcAncestor(L);
        recalcAncestor(R);
        Value l{VM::identity()}, r{VM::identity()};
        for ( ; L < R ; L = parent(L), R = parent(R)) {
            if (L & 1) {
                l = VM::operation(l, action(dat_[L]));
                L++;
            }
            if (R & 1) {
                R--;
                r = VM::operation(action(dat_[R]), r);
            }
        }
        return VM::operation(l, r);
    }
};

} // namespace zawa

struct VM {
    using Element = std::array<int, 4>;
    static Element identity() {
        Element res{};
        res.fill(0);
        return res;
    }
    static Element operation(Element L, const Element& R) {
        for (int i{} ; i < 4 ; i++) L[i] += R[i];
        return L;
    }
};

struct OM {
    using Element = int;
    static Element identity() {
        return 0;
    }
    static Element operation(Element L, Element R) {
        return L + R;
    }
};

struct Structure {
    using ValueMonoid = VM;
    using OperatorMonoid = OM;
    static VM::Element mapping(const VM::Element& A, const OM::Element& B) {
        int v{((B % 4) + 4) % 4};
        VM::Element res{VM::identity()};
        for (int i{} ; i < 4 ; i++) {
            res[(i + v) % 4] = A[i];
        }
        return res;
    }
};

using namespace zawa;

int main() {
    int N, M;
    std::cin >> N >> M;
    LazySegmentTree<Structure> seg(std::vector<VM::Element>(N, VM::Element{ 1, 0, 0, 0 }));
    while (M--) {
        int t;
        std::cin >> t;
        if (t == 1) {
            int L, R, v;
            std::cin >> L >> R >> v;
            L--;
            seg.operation(L, R, v);
        }
        else if (t == 2) {
            int L, R;
            std::cin >> L >> R;
            L--;
            auto val{seg.product(L, R)};
            std::cout << val[0] - val[2] << '\n';
        }
        else {
            assert(false);
        }
    }
}
accuracy: 1
time_ms: 150
memory_kb: 19568
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;


#include <algorithm>
#include <cassert>
#include <functional>
#include <vector>


#ifdef _MSC_VER
#include <intrin.h>
#endif

#if __cplusplus >= 202002L
#include <bit>
#endif

namespace atcoder {

namespace internal {

#if __cplusplus >= 202002L

using std::bit_ceil;

#else

unsigned int bit_ceil(unsigned int n) {
    unsigned int x = 1;
    while (x < (unsigned int)(n)) x *= 2;
    return x;
}

#endif

int countr_zero(unsigned int n) {
#ifdef _MSC_VER
    unsigned long index;
    _BitScanForward(&index, n);
    return index;
#else
    return __builtin_ctz(n);
#endif
}

constexpr int countr_zero_constexpr(unsigned int n) {
    int x = 0;
    while (!(n & (1 << x))) x++;
    return x;
}

}  // namespace internal

}  // namespace atcoder


namespace atcoder {

#if __cplusplus >= 201703L

template <class S,
          auto op,
          auto e,
          class F,
          auto mapping,
          auto composition,
          auto id>
struct lazy_segtree {
    static_assert(std::is_convertible_v<decltype(op), std::function<S(S, S)>>,
                  "op must work as S(S, S)");
    static_assert(std::is_convertible_v<decltype(e), std::function<S()>>,
                  "e must work as S()");
    static_assert(
        std::is_convertible_v<decltype(mapping), std::function<S(F, S)>>,
        "mapping must work as F(F, S)");
    static_assert(
        std::is_convertible_v<decltype(composition), std::function<F(F, F)>>,
        "compostiion must work as F(F, F)");
    static_assert(std::is_convertible_v<decltype(id), std::function<F()>>,
                  "id must work as F()");

#else

template <class S,
          S (*op)(S, S),
          S (*e)(),
          class F,
          S (*mapping)(F, S),
          F (*composition)(F, F),
          F (*id)()>
struct lazy_segtree {

#endif

  public:
    lazy_segtree() : lazy_segtree(0) {}
    explicit lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {}
    explicit lazy_segtree(const std::vector<S>& v) : _n(int(v.size())) {
        size = (int)internal::bit_ceil((unsigned int)(_n));
        log = internal::countr_zero((unsigned int)size);
        d = std::vector<S>(2 * size, e());
        lz = std::vector<F>(size, id());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) {
            update(i);
        }
    }

    void set(int p, S x) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        return d[p];
    }

    S prod(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return e();

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }

        S sml = e(), smr = e();
        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }

        return op(sml, smr);
    }

    S all_prod() { return d[1]; }

    void apply(int p, F f) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = mapping(f, d[p]);
        for (int i = 1; i <= log; i++) update(p >> i);
    }
    void apply(int l, int r, F f) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return;

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }

        {
            int l2 = l, r2 = r;
            while (l < r) {
                if (l & 1) all_apply(l++, f);
                if (r & 1) all_apply(--r, f);
                l >>= 1;
                r >>= 1;
            }
            l = l2;
            r = r2;
        }

        for (int i = 1; i <= log; i++) {
            if (((l >> i) << i) != l) update(l >> i);
            if (((r >> i) << i) != r) update((r - 1) >> i);
        }
    }

    template <bool (*g)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return g(x); });
    }
    template <class G> int max_right(int l, G g) {
        assert(0 <= l && l <= _n);
        assert(g(e()));
        if (l == _n) return _n;
        l += size;
        for (int i = log; i >= 1; i--) push(l >> i);
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!g(op(sm, d[l]))) {
                while (l < size) {
                    push(l);
                    l = (2 * l);
                    if (g(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, d[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }

    template <bool (*g)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return g(x); });
    }
    template <class G> int min_left(int r, G g) {
        assert(0 <= r && r <= _n);
        assert(g(e()));
        if (r == 0) return 0;
        r += size;
        for (int i = log; i >= 1; i--) push((r - 1) >> i);
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!g(op(d[r], sm))) {
                while (r < size) {
                    push(r);
                    r = (2 * r + 1);
                    if (g(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

  private:
    int _n, size, log;
    std::vector<S> d;
    std::vector<F> lz;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
    void all_apply(int k, F f) {
        d[k] = mapping(f, d[k]);
        if (k < size) lz[k] = composition(f, lz[k]);
    }
    void push(int k) {
        all_apply(2 * k, lz[k]);
        all_apply(2 * k + 1, lz[k]);
        lz[k] = id();
    }
};

}  // namespace atcoder

using namespace atcoder;

using S = array<int, 2>;
using F = array<int, 2>;

S op(S x, S y) {
  return S{x[0]+y[0], x[1]+y[1]};
}

S e() {
  return S{0, 0};
}

S mapping(F f, S x) {
  return S{x[0]*f[0]-x[1]*f[1], x[1]*f[0]+x[0]*f[1]};
}

F composition(F f, F g) {
  return F{f[0]*g[0]-f[1]*g[1], f[1]*g[0]+f[0]*g[1]};
}

F id() {
  return F{1, 0};
}

int main() {
  int N, M;
  cin >> N >> M;
  vector<S> student(N, S{1, 0});
  lazy_segtree<S, op, e, F, mapping, composition, id> seg(student);
  for( int i = 0; i < M; i++ ) {
    int t;
    cin >> t;
    if( t == 1 ) {
      int a, b, c;
      cin >> a >> b >> c;
      for( int j = 0; j < abs(c)%4; j++ ) {
        seg.apply(a-1, b, F{0, c/abs(c)});
      }
    }else {
      int a, b;
      cin >> a >> b;
      cout << seg.prod(a-1, b)[0] << endl;
    }
  }
}
accuracy: 1
time_ms: 120
memory_kb: 17684
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;


#include <algorithm>
#include <cassert>
#include <functional>
#include <vector>


#ifdef _MSC_VER
#include <intrin.h>
#endif

#if __cplusplus >= 202002L
#include <bit>
#endif

namespace atcoder {

namespace internal {

#if __cplusplus >= 202002L

using std::bit_ceil;

#else

unsigned int bit_ceil(unsigned int n) {
    unsigned int x = 1;
    while (x < (unsigned int)(n)) x *= 2;
    return x;
}

#endif

int countr_zero(unsigned int n) {
#ifdef _MSC_VER
    unsigned long index;
    _BitScanForward(&index, n);
    return index;
#else
    return __builtin_ctz(n);
#endif
}

constexpr int countr_zero_constexpr(unsigned int n) {
    int x = 0;
    while (!(n & (1 << x))) x++;
    return x;
}

}  // namespace internal

}  // namespace atcoder


namespace atcoder {

#if __cplusplus >= 201703L

template <class S,
          auto op,
          auto e,
          class F,
          auto mapping,
          auto composition,
          auto id>
struct lazy_segtree {
    static_assert(std::is_convertible_v<decltype(op), std::function<S(S, S)>>,
                  "op must work as S(S, S)");
    static_assert(std::is_convertible_v<decltype(e), std::function<S()>>,
                  "e must work as S()");
    static_assert(
        std::is_convertible_v<decltype(mapping), std::function<S(F, S)>>,
        "mapping must work as F(F, S)");
    static_assert(
        std::is_convertible_v<decltype(composition), std::function<F(F, F)>>,
        "compostiion must work as F(F, F)");
    static_assert(std::is_convertible_v<decltype(id), std::function<F()>>,
                  "id must work as F()");

#else

template <class S,
          S (*op)(S, S),
          S (*e)(),
          class F,
          S (*mapping)(F, S),
          F (*composition)(F, F),
          F (*id)()>
struct lazy_segtree {

#endif

  public:
    lazy_segtree() : lazy_segtree(0) {}
    explicit lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {}
    explicit lazy_segtree(const std::vector<S>& v) : _n(int(v.size())) {
        size = (int)internal::bit_ceil((unsigned int)(_n));
        log = internal::countr_zero((unsigned int)size);
        d = std::vector<S>(2 * size, e());
        lz = std::vector<F>(size, id());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) {
            update(i);
        }
    }

    void set(int p, S x) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        return d[p];
    }

    S prod(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return e();

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }

        S sml = e(), smr = e();
        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }

        return op(sml, smr);
    }

    S all_prod() { return d[1]; }

    void apply(int p, F f) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = mapping(f, d[p]);
        for (int i = 1; i <= log; i++) update(p >> i);
    }
    void apply(int l, int r, F f) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return;

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }

        {
            int l2 = l, r2 = r;
            while (l < r) {
                if (l & 1) all_apply(l++, f);
                if (r & 1) all_apply(--r, f);
                l >>= 1;
                r >>= 1;
            }
            l = l2;
            r = r2;
        }

        for (int i = 1; i <= log; i++) {
            if (((l >> i) << i) != l) update(l >> i);
            if (((r >> i) << i) != r) update((r - 1) >> i);
        }
    }

    template <bool (*g)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return g(x); });
    }
    template <class G> int max_right(int l, G g) {
        assert(0 <= l && l <= _n);
        assert(g(e()));
        if (l == _n) return _n;
        l += size;
        for (int i = log; i >= 1; i--) push(l >> i);
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!g(op(sm, d[l]))) {
                while (l < size) {
                    push(l);
                    l = (2 * l);
                    if (g(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, d[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }

    template <bool (*g)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return g(x); });
    }
    template <class G> int min_left(int r, G g) {
        assert(0 <= r && r <= _n);
        assert(g(e()));
        if (r == 0) return 0;
        r += size;
        for (int i = log; i >= 1; i--) push((r - 1) >> i);
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!g(op(d[r], sm))) {
                while (r < size) {
                    push(r);
                    r = (2 * r + 1);
                    if (g(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

  private:
    int _n, size, log;
    std::vector<S> d;
    std::vector<F> lz;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
    void all_apply(int k, F f) {
        d[k] = mapping(f, d[k]);
        if (k < size) lz[k] = composition(f, lz[k]);
    }
    void push(int k) {
        all_apply(2 * k, lz[k]);
        all_apply(2 * k + 1, lz[k]);
        lz[k] = id();
    }
};

}  // namespace atcoder

using namespace atcoder;

using S = array<int, 2>;
using F = array<int, 2>;

S op(S x, S y) {
  return S{x[0]+y[0], x[1]+y[1]};
}

S e() {
  return S{0, 0};
}

S mapping(F f, S x) {
  return S{x[0]*f[0]-x[1]*f[1], x[1]*f[0]+x[0]*f[1]};
}

F composition(F f, F g) {
  return F{f[0]*g[0]-f[1]*g[1], f[1]*g[0]+f[0]*g[1]};
}

F id() {
  return F{1, 0};
}

int main() {
  int N, M;
  cin >> N >> M;
  vector<S> student(N, S{1, 0});
  lazy_segtree<S, op, e, F, mapping, composition, id> seg(student);
  for( int i = 0; i < M; i++ ) {
    int t;
    cin >> t;
    if( t == 1 ) {
      int a, b, c;
      cin >> a >> b >> c;
      for( int j = 0; j < abs(c)%4; j++ ) {
        seg.apply(a-1, b, c < 0 ? F{0, 1} : F{0, -1});
      }
    }else {
      int a, b;
      cin >> a >> b;
      cout << seg.prod(a-1, b)[0] << endl;
    }
  }
}
accuracy: 1
time_ms: 120
memory_kb: 17860
final_rank: 2

code_snippet: #include <bits/stdc++.h>

using Data = std::array<int, 4>;
const int D = 1000000000;

Data op(const Data& lhs, const Data& rhs) {
    Data data;
    data.fill(0);
    for (int i = 0; i < 4; i++) {
        data[i] = lhs[i] + rhs[i];
    }
    return data;
}

Data mapping(const Data& data, int lazy) {
    lazy = (lazy + D) % 4;
    Data res;
    for (int i = 0; i < 4; i++) {
        res[i] = data[(i + lazy) % 4];
    }
    return res;
}

struct SegmentTree {
    std::vector<Data> data;
    std::vector<int> lazy;
    int size;
    SegmentTree(int n) {
        int log = 0;
        while (n > (1 << log)) log++;
        size = 1 << log;
        data.assign(2 * size, {1, 0, 0, 0});
        lazy.assign(2 * size, 0);
        for (int i = size - 1; i > 0; i--) {
            data[i] = op(data[2 * i], data[2 * i + 1]);
        }
    }
    void push(int pos) {
        std::vector<int> stack;
        for (int i = pos + size; i > 0; i >>= 1) stack.push_back(i);
        std::reverse(stack.begin(), stack.end());
        stack.pop_back();
        for (auto i: stack) {
            assert(i < size);
            data[2 * i] = mapping(data[2 * i], lazy[i]);
            data[2 * i + 1] = mapping(data[2 * i + 1], lazy[i]);
            lazy[2 * i] += lazy[i];
            lazy[2 * i + 1] += lazy[i];
            lazy[i] = 0;
        }
    }
    void update(int pos) {
        pos += size;
        pos >>= 1;
        for (; pos > 0; pos >>= 1) {
            data[2 * pos] = mapping(data[2 * pos], lazy[pos]);
            data[2 * pos + 1] = mapping(data[2 * pos + 1], lazy[pos]);
            lazy[2 * pos] += lazy[pos];
            lazy[2 * pos + 1] += lazy[pos];
            lazy[pos] = 0;
            data[pos] = op(data[2 * pos], data[2 * pos + 1]);
        }
    }
    void apply(int left, int right, int val) {
        int l = left;
        int r = right;
        push(left);
        push(right - 1);
        for (left += size, right += size; left < right; left >>= 1, right >>= 1) {
            if (left & 1) {
                data[left] = mapping(data[left], val);
                lazy[left] += val;
                left++;
            }
            if (right & 1) {
                right--;
                data[right] = mapping(data[right], val);
                lazy[right] += val;
            }
        }
        update(l);
        update(r - 1);
    }
    Data prod(int left, int right) {
        push(left);
        push(right - 1);
        Data res;
        res.fill(0);
        for (left += size, right += size; left < right; left >>= 1, right >>= 1) {
            if (left & 1) res = op(res, data[left++]);
            if (right & 1) res = op(res, data[--right]);
        }
        return res;
    }
    Data get(int pos) {
        push(pos);
        return data[pos + size];
    }
};

int main() {
    int n, m;
    std::cin >> n >> m;
    SegmentTree segtree(n);
    for (int i = 0; i < m; i++) {
        int t;
        std::cin >> t;
        if (t == 1) {
            int l, r, v;
            std::cin >> l >> r >> v;
            l--;
            segtree.apply(l, r, v);
        } else {
            int l, r;
            std::cin >> l >> r;
            l--;
            auto data = segtree.prod(l, r);
            // for (int k = 0; k < 4; k++) {
            //     std::cerr << data[k] << ' ';
            // }
            // std::cerr << std::endl;
            std::cout << data[0] - data[2] << '\n';
        }
        // std::cerr << "turn " << i << '\n';
        // for (int j = 0; j < n; j++) {
        //     auto data = segtree.get(j);
        //     std::cerr << j << ": ";
        //     for (int k = 0; k < 4; k++) {
        //         std::cerr << data[k] << ' ';
        //     }
        //     std::cerr << '\n';
        // }
    }
}
accuracy: 1
time_ms: 210
memory_kb: 23604
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, n) for (int i = 0; i < n; i++)
#define all(v) v.begin(), v.end()
template <class T, class U>
inline bool chmax(T &a, U b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
template <class T, class U>
inline bool chmin(T &a, U b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
constexpr int INF = 1000000000;
constexpr ll llINF = 3000000000000000000;
constexpr double pi = 3.141592653589793238;
constexpr double eps = 1e-10;
struct segtree {
    int siz = 1;
    vector<int> dat;
    segtree(int n) : segtree(vector<int>(n, 0)) {}
    segtree(const vector<int> &a) {
        while (siz < a.size()) siz <<= 1;
        dat = vector<int>(siz << 1, 0);
        for (int i = 0; i < a.size(); i++) dat[siz + i] = a[i];
        for (int i = siz - 1; i >= 1; i--) dat[i] = dat[2 * i] + dat[2 * i + 1];
    }
    void set(int p, int x) {
        p += siz;
        dat[p] = x;
        while (p > 0) {
            p >>= 1;
            dat[p] = dat[2 * p] + dat[2 * p + 1];
        }
    }
    int prod(int l, int r) {
        int vl = 0, vr = 0;
        l += siz, r += siz;
        while (l < r) {
            if (l & 1) vl = vl + dat[l++];
            if (r & 1) vr = dat[--r] + vr;
            l >>= 1, r >>= 1;
        }
        return vl + vr;
    }
};
struct BIT {
    // 1-indexed
    int n, beki = 1;
    vector<int> bit;
    BIT(int x) {
        bit.resize(x + 1, 0);
        n = x;
        while (beki * 2 <= n) beki *= 2;
    }
    int sum(int i) {
        int res = 0;
        while (i > 0) {
            res += bit[i];
            i -= i & -i;
        }
        return res;
    }
    int sum(int l, int r) {
        //[l,r]
        return sum(r) - (l == 0 ? 0 : sum(l - 1));
    }
    void add(int i, int x) {
        while (i <= n) {
            bit[i] += x;
            i += i & -i;
        }
    }
};
template <class S, S (*op)(S, S), S (*e)(), class F, S (*mapping)(F, S), F (*composition)(F, F), F (*id)()>
struct lazy_segtree {
    int _n, sz = 1;
    vector<S> dat;
    vector<F> lazy;
    lazy_segtree(vector<S> a) : _n(int(a.size())) {
        while (sz < _n) sz <<= 1;
        dat.resize(sz * 2, e());
        lazy.resize(sz * 2, id());
        rep(i, _n) dat[sz + i] = a[i];
        for (int i = sz - 1; i >= 1; i--) dat[i] = op(dat[2 * i], dat[2 * i + 1]);
    }
    void eval(int k) {
        dat[k] = mapping(lazy[k], dat[k]);
        if (k < sz) {
            lazy[k * 2] = composition(lazy[k], lazy[k * 2]);
            lazy[k * 2 + 1] = composition(lazy[k], lazy[k * 2 + 1]);
        }
        lazy[k] = id();
    }
    void apply(int a, int b, F f, int k = 1, int l = 0, int r = -1) {
        eval(k);
        if (r == -1) r = sz;
        if (r <= a || b <= l) return;
        if (a <= l && r <= b) {
            lazy[k] = composition(f, lazy[k]);
            eval(k);
            return;
        }
        int m = (l + r) >> 1;
        apply(a, b, f, 2 * k, l, m);
        apply(a, b, f, 2 * k + 1, m, r);
        dat[k] = op(dat[2 * k], dat[2 * k + 1]);
    }
    S prod(int a, int b, int k = 1, int l = 0, int r = -1) {
        eval(k);
        if (r == -1) r = sz;
        if (r <= a || b <= l) return e();
        if (a <= l && r <= b) return dat[k];
        int m = (l + r) >> 1;
        S vl = prod(a, b, 2 * k, l, m);
        S vr = prod(a, b, 2 * k + 1, m, r);
        return op(vl, vr);
    }
};
using S = array<int, 4>;
using F = int;
S op(S a, S b) { return {a[0] + b[0], a[1] + b[1], a[2] + b[2], a[3] + b[3]}; }
S e() { return {0, 0, 0, 0}; }
S mapping(F f, S a) { return {a[(f + 1000000000) % 4], a[(f + 1000000001) % 4], a[(f + 1000000002) % 4], a[(f + 1000000003) % 4]}; }
F composition(F f, F g) { return f + g; }
F id() { return 0; }
int main() {
    int n, m;
    cin >> n >> m;
    lazy_segtree<S, op, e, F, mapping, composition, id> seg(vector<S>(n, {1, 0, 0, 0}));
    while (m--) {
        int type;
        cin >> type;
        if (type == 1) {
            int a, b, c;
            cin >> a >> b >> c;
            a--;
            seg.apply(a, b, c);
        } else {
            int d, e;
            cin >> d >> e;
            d--;
            auto res = seg.prod(d, e);
            cout << res[0] - res[2] << endl;
        }
    }
}
accuracy: 1
time_ms: 150
memory_kb: 28364
final_rank: 13

code_snippet: #include <string.h>
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <memory>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;

void mpl(int &x,int y) {
    x += y;
    if(x >= 4) x -= 4;
}

template <typename T>
struct LazySegmentTree {
    int n;
    vector<T> dat;
    vector<int>lazy;
    LazySegmentTree() {};
    LazySegmentTree(int N) {
        n = 1;
        while(n < N) {
            n *= 2;
        }
        dat.resize(n*2);
        lazy.resize(n*2,0);
        for(int i = n; i < 2*n; i++) {
            dat[i] = {1,0,0,0};
        }
        for(int i = n-1; i >= 1; i--) {
            dat[i] = {dat[i*2][0]+dat[i*2+1][0],0,0,0};
        }
    }
    void eval(int k,int l,int r) {
        if(lazy[k] == 0) return;
        if(k < n) {
            mpl(lazy[k*2],lazy[k]);
            mpl(lazy[k*2+1],lazy[k]);
        }
        vector<int>nxt(4);
        for(int i = 0; i < 4; i++) {
            nxt[(lazy[k]+i)%4] = dat[k][i];
        }
        dat[k] = nxt;
        lazy[k] = 0;
    }
    void update(int a, int b, int x, int k, int l, int r) {
        eval(k,l,r);
        if(a <= l && r <= b) {
            mpl(lazy[k],x);
            eval(k,l,r);
        }
        else if(a < r && l < b) {
            update(a, b, x, k*2, l, (l+r)/2);
            update(a, b, x, k*2+1, (l+r)/2, r);
            for(int i = 0; i < 4; i++) {
                dat[k][i] = dat[k*2][i]+dat[k*2+1][i];
            }
        }
    }
    void update(int a, int b, int x) {//[a,b)
        update(a, b, x, 1, 0, n);
    }
    T query_sub(int a, int b, int k, int l, int r) {
        eval(k,l,r);
        if (r <= a || b <= l) {
            return {0,0,0,0};
        }
        else if (a <= l && r <= b) {
            return dat[k];
        }
        else {
            T vl = query_sub(a, b, k*2, l, (l+r)/2);
            T vr = query_sub(a, b, k*2+1, (l+r)/2, r);
            vector<int>ans(4);
            for(int i = 0; i < 4; i++) ans[i] = vl[i]+vr[i];
            return ans;
        }
    }
    T query(int a, int b) {//[a,b)
        return query_sub(a, b, 1, 0, n);
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int N,M;
    cin >> N >> M;
    LazySegmentTree<vector<int>>Seg(N);
    for(int i = 0; i < M; i++) {
        int f;
        cin >> f;
        if(f == 1) {
            int a,b,c;
            cin >> a >> b >> c;
            a--;
            Seg.update(a,b,(c%4+4)%4);
        }
        else {
            int d,e;
            cin >> d >> e;
            d--;
            auto a = Seg.query(d,e);
            cout << a[0]-a[2] << "\n";
        }
    }
}
accuracy: 1
time_ms: 290
memory_kb: 64468
final_rank: 17

code_snippet: /* -*- coding: utf-8 -*-
 *
 * 0464.cc: Rotating Mass Game
 */

#include<cstdio>
#include<vector>
#include<algorithm>
 
using namespace std;

/* constant */

const int MAX_N = 300000;

/* typedef */

struct Elm {
  int vs[4];
  Elm(): vs() {}
  Elm(int _a, int _b, int _c, int _d) {
    vs[0] = _a, vs[1] = _b, vs[2] = _c, vs[3] = _d;
  }

  Elm operator+(const Elm &e) const {
    Elm r;
    for (int i = 0; i < 4; i++) r.vs[i] = vs[i] + e.vs[i];
    return r;
  }

  void rot(int c) {
    int tmp[4];
    for (int i = 0; i < 4; i++) tmp[(i + c) & 3] = vs[i];
    copy(tmp, tmp + 4, vs);
  }
};

struct SegTreeDelay {
  typedef Elm T;
  int e2;
  vector<T> nodes;
  T defv;
  vector<int> dls;
  SegTreeDelay() {}

  void init(int n, T _defv) {
    defv = _defv;
    for (e2 = 1; e2 < n; e2 <<= 1);
    nodes.assign(e2 * 2, defv);
    dls.assign(e2 * 2, 0);
  }

  T &geti(int i) { return nodes[e2 - 1 + i]; }
  void seti(int i, T v) { geti(i) = v; }

  void setall() {
    for (int j = e2 - 2; j >= 0; j--)
      nodes[j] = nodes[j * 2 + 1] + nodes[j * 2 + 2];
  }

  void __update(int k) {
    if (dls[k]) {
      int k0 = k * 2 + 1, k1 = k0 + 1;
      nodes[k0].rot(dls[k]);
      nodes[k1].rot(dls[k]);
      dls[k0] = (dls[k0] + dls[k]) & 3;
      dls[k1] = (dls[k1] + dls[k]) & 3;
      dls[k] = 0;
    }
  }

  void rot_range(int r0, int r1, int c, int k, int i0, int i1) {
    if (r1 <= i0 || i1 <= r0) return;
    if (r0 <= i0 && i1 <= r1) {
      nodes[k].rot(c);
      dls[k] = (dls[k] + c) & 3;
      return;
    }

    __update(k);

    int im = (i0 + i1) / 2;
    int k0 = k * 2 + 1, k1 = k0 + 1;
    rot_range(r0, r1, c, k0, i0, im);
    rot_range(r0, r1, c, k1, im, i1);
    nodes[k] = nodes[k0] + nodes[k1];
  }
  void rot_range(int r0, int r1, int c) { rot_range(r0, r1, c, 0, 0, e2); }

  T sum_range(int r0, int r1, int k, int i0, int i1) {
    if (r1 <= i0 || i1 <= r0) return defv;
    if (r0 <= i0 && i1 <= r1) return nodes[k];

    __update(k);

    int im = (i0 + i1) / 2;
    T v0 = sum_range(r0, r1, k * 2 + 1, i0, im);
    T v1 = sum_range(r0, r1, k * 2 + 2, im, i1);
    return v0 + v1;
  }
  T sum_range(int r0, int r1) { return sum_range(r0, r1, 0, 0, e2); }
};

/* global variables */

SegTreeDelay st;

/* subroutines */

/* main */

int main() {
  int n, m;
  scanf("%d%d", &n, &m);

  st.init(n, Elm(0, 0, 0, 0));
  for (int i = 0; i < n; i++) st.seti(i, Elm(1, 0, 0, 0));
  st.setall();

  while (m--) {
    int op;
    scanf("%d", &op);

    if (op == 1) {
      int l, r, c;
      scanf("%d%d%d", &l, &r, &c), l--;
      st.rot_range(l, r, c);
    }
    else {
      int l, r;
      scanf("%d%d", &l, &r), l--;

      Elm e = st.sum_range(l, r);
      printf("%d\n", e.vs[0] - e.vs[2]);
    }
  }

  return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 23060
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
#if __has_include(<atcoder/all>)
#include <atcoder/all>
using namespace atcoder;
#endif
using ll = long long;
using ld = long double;
using ull = unsigned long long;
#define endl "\n"
typedef pair<int, int> Pii;
#define REP(i, n) for (int i = 0; i < (n); ++i)
#define REP3(i, m, n) for (int i = (m); (i) < int(n); ++ (i))
#define FOR(i,a,b) for(ll i=a;i<=(ll)(b);i++)
#define rep(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define ALL(x) begin(x), end(x)
#define rrep(i,a,b) for(int i=a;i>=b;i--)
#define fore(i,a) for(auto &i:a)
#define all(s) (s).begin(),(s).end()
#define drep2(i, m, n) for (int i = (m)-1; i >= (n); --i)
#define drep(i, n) drep2(i, n, 0)
#define rever(vec) reverse(vec.begin(), vec.end())
#define sor(vec) sort(vec.begin(), vec.end())
#define fi first
#define se second
#define pb push_back
#define P pair<ll,ll>
#define PQminll priority_queue<ll, vector<ll>, greater<ll>>
#define PQmaxll priority_queue<ll,vector<ll>,less<ll>>
#define PQminP priority_queue<P, vector<P>, greater<P>>
#define PQmaxP priority_queue<P,vector<P>,less<P>>
#define NP next_permutation
//const ll mod = 1000000009;
const ll mod = 998244353;
//const ll mod = 1000000007;
const ll inf = 4100000000000000000ll;
const ld eps = ld(0.00000000001);
static const long double pi = 3.141592653589793;
template<class T>void vcin(vector<T> &n){for(int i=0;i<int(n.size());i++) cin>>n[i];}
template<class T,class K>void vcin(vector<T> &n,vector<K> &m){for(int i=0;i<int(n.size());i++) cin>>n[i]>>m[i];}
template<class T>void vcout(vector<T> &n){for(int i=0;i<int(n.size());i++){cout<<n[i]<<" ";}cout<<endl;}
template<class T>void vcin(vector<vector<T>> &n){for(int i=0;i<int(n.size());i++){for(int j=0;j<int(n[i].size());j++){cin>>n[i][j];}}}
template<class T>void vcout(vector<vector<T>> &n){for(int i=0;i<int(n.size());i++){for(int j=0;j<int(n[i].size());j++){cout<<n[i][j]<<" ";}cout<<endl;}cout<<endl;}
void yes(bool a){cout<<(a?"yes":"no")<<endl;}
void YES(bool a){cout<<(a?"YES":"NO")<<endl;}
void Yes(bool a){cout<<(a?"Yes":"No")<<endl;}
void possible(bool a){ cout<<(a?"possible":"impossible")<<endl; }
void Possible(bool a){ cout<<(a?"Possible":"Impossible")<<endl; }
void POSSIBLE(bool a){ cout<<(a?"POSSIBLE":"IMPOSSIBLE")<<endl; }
template<class T>auto min(const T& a){ return *min_element(all(a)); }
template<class T>auto max(const T& a){ return *max_element(all(a)); }
template<class T,class F>void print(pair<T,F> a){cout<<a.fi<<" "<<a.se<<endl;}
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0;}
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0;}
template<class T> void ifmin(T t,T u){if(t>u){cout<<-1<<endl;}else{cout<<t<<endl;}}
template<class T> void ifmax(T t,T u){if(t>u){cout<<-1<<endl;}else{cout<<t<<endl;}}
ll fastgcd(ll u,ll v){ll shl=0;while(u&&v&&u!=v){bool eu=!(u&1);bool ev=!(v&1);if(eu&&ev){++shl;u>>=1;v>>=1;}else if(eu&&!ev){u>>=1;}else if(!eu&&ev){v>>=1;}else if(u>=v){u=(u-v)>>1;}else{ll tmp=u;u=(v-u)>>1;v=tmp;}}return !u?v<<shl:u<<shl;}
ll modPow(ll a, ll n, ll mod) { if(mod==1) return 0;ll ret = 1; ll p = a % mod; while (n) { if (n & 1) ret = ret * p % mod; p = p * p % mod; n >>= 1; } return ret; }
vector<ll> divisor(ll x){ vector<ll> ans; for(ll i = 1; i * i <= x; i++){ if(x % i == 0) {ans.push_back(i); if(i*i!=x){ ans.push_back(x / ans[i]);}}}sor(ans); return ans; }
ll pop(ll x){return __builtin_popcountll(x);}
ll poplong(ll x){ll y=-1;while(x){x/=2;y++;}return y;}
P hyou(P a){ll x=fastgcd(abs(a.fi),abs(a.se));a.fi/=x;a.se/=x;if(a.se<0){a.fi*=-1;a.se*=-1;}return a;}
P Pplus(P a,P b){ return hyou({a.fi*b.se+b.fi*a.se,a.se*b.se});}
P Ptimes(P a,ll b){ return hyou({a.fi*b,a.se});}
P Ptimes(P a,P b){ return hyou({a.fi*b.fi,a.se*b.se});}
P Pminus(P a,P b){ return hyou({a.fi*b.se-b.fi*a.se,a.se*b.se});}
P Pgyaku(P a){ return hyou({a.se,a.fi});}
template<class T>
struct Sum{
  vector<T> data;
  Sum(const vector<T>& v):data(v.size()+1){
    for(ll i=0;i<v.size();i++) data[i+1]=data[i]+v[i];
  }
  T get(ll l,ll r) const {
    return data[r]-data[l];
  }
};
template<class T>
struct Sum2{
  vector<vector<T>> data;
  Sum2(const vector<vector<T>> &v):data(v.size()+1,vector<T>(v[0].size()+1)){
    for(int i=0;i<v.size();i++) for(int j=0;j<v[i].size();j++) data[i+1][j+1]=data[i][j+1]+v[i][j];
    for(int i=0;i<v.size();i++) for(int j=0;j<v[i].size();j++) data[i+1][j+1]+=data[i+1][j];
  }
  T get(ll x1,ll y1,ll x2,ll y2) const {
    return data[x2][y2]+data[x1][y1]-data[x1][y2]-data[x2][y1];
  }
};

void cincout(){
  ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
  cout<< fixed << setprecision(15);
}
struct lazysegtree{
  vector<vector<ll>> node;
  vector<ll> lazy;
  ll n;
  vector<ll> merge(vector<ll> a,vector<ll> b){
    for(int i=0;i<4;i++) a[i]+=b[i];
    return a;
  }
  lazysegtree(ll N){
    ll x=1;
    while(x<N) x*=2;
    n=x;
    node.resize(2*n);
    lazy.resize(2*n);
    for(int i=n;i<2*n;i++){
      node[i].resize(4);
      if(i<n+N) node[i][0]=1;
    }
    for(int i=n-1;i>=1;i--){
      node[i]=merge(node[2*i],node[2*i+1]);
    }
  }
  void eval(ll k){
    if(lazy[k]==0) return;
    if(k<n){
      lazy[2*k]+=lazy[k];
      lazy[2*k+1]+=lazy[k];
    }
    vector<ll> d(4);
    for(int i=0;i<4;i++) d[(i+lazy[k])%4]=node[k][i];
    node[k]=d;
    lazy[k]=0;
  }
  void update(ll a,ll b,ll k,ll l,ll r,ll x){
    eval(k);
    if(a>=r||l>=b) return;
    if(a<=l&&r<=b){
      lazy[k]+=x;
      eval(k);
      return;
    }
    update(a,b,2*k,l,(l+r)/2,x);
    update(a,b,2*k+1,(l+r)/2,r,x);
    node[k]=merge(node[2*k],node[2*k+1]);
  }
  void update(ll a,ll b,ll x){
    update(a,b,1,0,n,x);
  }
  vector<ll> query(ll a,ll b,ll k,ll l,ll r){
    eval(k);
    if(a>=r||l>=b) return {0,0,0,0};
    if(a<=l&&r<=b){
      return node[k];
    }
    return merge(query(a,b,2*k,l,(l+r)/2),query(a,b,2*k+1,(l+r)/2,r));
  }
  vector<ll> query(ll a,ll b){
    return query(a,b,1,0,n);
  }
};
int main() {
  cincout();
  ll n,m;
  cin>>n>>m;
  lazysegtree seg(n);
  for(int i=0;i<m;i++){
    ll t;
    cin>>t;
    if(t==1){
      ll a,b,c;
      cin>>a>>b>>c;
      a--;
      b--;
      c+=1000;
      c%=4;
      seg.update(a,b+1,c);
    }
    else{
      ll a,b;
      cin>>a>>b;
      a--;
      b--;
      vector<ll> q=seg.query(a,b+1);
      cout<<q[0]-q[2]<<endl;
    }
  }
}
accuracy: 1
time_ms: 370
memory_kb: 85020
final_rank: 20

code_snippet: #include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <algorithm>
#include <utility>
#include <tuple>
#include <cstdint>
#include <cstdio>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <deque>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <cctype>
#include <climits>
#include <functional>
#include <cassert>
#include <numeric>
#define rep(i, n) for(int i = 0; i < (n); i++)
#define per(i, n) for(int i = (n) - 1; i >= 0; i--)
using ll = long long;
#define vi vector<int>
#define vvi vector<vi>
#define vl vector<ll>
#define pii pair<int, int>
#define pll pair<ll, ll>
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define mod 1000000007
using namespace std;
template<class T, class U>
bool chmax(T &a, const U &b){ return a < b ? (a = b, 1) : 0; }
template<class T, class U>
bool chmin(T &a, const U &b){ return a > b ? (a = b, 1) : 0; }
template <class T, T(*op)(const T&,const T&), T(*e)(), class F,
          T(*mapping)(const F&,const T&), F(*composition)(const F&,const F&), F(*id)()>
struct LazySegmentTree {
  LazySegmentTree(int _n) : n(_n){
    while((1 << log) < n) log++;
    len = 1 << log;
    d.assign(len * 2, e());
    lazy.assign(len, id());
  }
  void set(const int &i, const T &x){
    assert(0 <= i && i < n);
    d[i + len] = x;
  }
  T get(int p){
    assert(0 <= p && p < n);
    p += len;
    for(int i = log; i >= 1; i--) push(p >> i);
    return d[p];
  }
  void build(){
    for(int i = len - 1; i >= 1; i--) update(i);
  }
  void update(int l, int r, const F &x){
    assert(0 <= l && l <= r && r <= n);
    l += len; r += len;
    const int l_ctz = __builtin_ctz(l);
    const int r_ctz = __builtin_ctz(r);
    for(int i = log; i > l_ctz; i--) push(l >> i);
    for(int i = log; i > r_ctz; i--) push((r - 1) >> i);
    const int lt = l, rt = r;
    while(l < r){
      if(l & 1) apply(l++, x);
      if(r & 1) apply(--r, x);
      l >>= 1; r >>= 1;
    }
    l = lt; r = rt;
    for(int i = l_ctz + 1; i <= log; i++) update(l >> i);
    for(int i = r_ctz + 1; i <= log; i++) update((r - 1) >> i);
  }
  T query(int l, int r){
    assert(0 <= l && l <= r && r <= n);
    l += len; r += len;
    const int l_ctz = __builtin_ctz(l);
    const int r_ctz = __builtin_ctz(r);
    for(int i = log; i > l_ctz; i--) push(l >> i);
    for(int i = log; i > r_ctz; i--) push((r - 1) >> i);
    T left = e(), right = e();
    while(l < r){
      if(l & 1) left = op(left, d[l++]);
      if(r & 1) right = op(d[--r], right);
      l >>= 1; r >>= 1;
    }
    return op(left, right);
  }
  private:
  vector<T> d;
  vector<F> lazy;
  int n = 1, log = 0, len = 0;
  void update(const int &k){ d[k] = op(d[2*k], d[2*k+1]); }
  void apply(const int &k, const F &x){
    d[k] = mapping(x, d[k]);
    if(k < len) lazy[k] = composition(lazy[k], x);
  }
  void push(const int &k){
    apply(2*k, lazy[k]);
    apply(2*k+1, lazy[k]);
    lazy[k] = id();
  }
};
using Data = array<int, 4>;
using Lazy = int;
Data op(const Data &a, const Data &b){
  Data res = {};
  rep(i, 4) res[i] = a[i] + b[i];
  return res;
}
Data e(){
  return { 0, 0, 0, 0 };
}
Data mapping(const Lazy &a, const Data &b){
  Data res = {};
  rep(i, 4) res[(i+4+a) % 4] = b[i];
  return res;
}
Lazy composition(const Lazy &a, const Lazy &b){
  return (a + b + 8) % 4;
}
Lazy id(){
  return 0;
}
int main(){
  int n,m;
  cin >> n >> m;
  LazySegmentTree<Data,op,e,Lazy,mapping,composition,id> seg(n);
  rep(i, n) seg.set(i, { 1, 0, 0, 0 });
  seg.build();
  rep(i, m){
    int t;
    cin >> t;
    if(t == 1){
      int a,b,c;
      cin >> a >> b >> c;
      seg.update(a-1, b, c % 4);
    }else{
      int d,e;
      cin >> d >> e;
      const Data res = seg.query(d-1, e);
      cout << res[0] - res[2] << "\n";
    }
  }
}
accuracy: 1
time_ms: 160
memory_kb: 21464
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define emb emplace_back
#define all(v) (v).begin(),(v).end()
using ll = long long;
using S = array<int,4>;
using F = int;
S op(const S &l,const S &r){return {l[0]+r[0],l[1]+r[1],l[2]+r[2],l[3]+r[3]};}
void apply(S &l,const F x){
  static S ret;
  for(int i=0;i<4;i++) ret[(i+x)%4] = l[i];
  for(int i=0;i<4;i++) l[i] = ret[i];
}
class lazysegtree{
  int N;vector<S> data;vector<F> lazy;
  void eval(int itr){
    apply(data[itr],lazy[itr]);
    if(itr<N){
      lazy[itr<<1] = (lazy[itr<<1]+lazy[itr])%4;
      lazy[itr<<1|1] = (lazy[itr<<1|1]+lazy[itr])%4;
    }
    lazy[itr] = 0;
  }
  void update(int l,int r,F x,int itr,int a,int b){
    eval(itr);
    if(b<=l || r<=a) return;
    if(l<=a && b<=r){
      lazy[itr] = x;eval(itr);
    }
    else{
      update(l,r,x,itr<<1,a,(a+b)>>1);
      update(l,r,x,itr<<1|1,(a+b)>>1,b);
      data[itr] = op(data[itr<<1],data[itr<<1|1]);
    }
  }
  S query(int l,int r,int itr,int a,int b){
    if(b<=l || r<=a) return {0,0,0,0};
    eval(itr);
    if(l<=a && b<=r) return data[itr];
    else return op(query(l,r,itr<<1,a,(a+b)>>1),query(l,r,itr<<1|1,(a+b)>>1,b));
  }
public:
  lazysegtree(int I_N){
    N = 1;
    while(N < I_N) N <<= 1;
    data.resize(N<<1);lazy.resize(N<<1);
    for(int i=N;i<(N<<1);i++) data[i] = {1,0,0,0};
    for(int i=N-1;i>=1;i--) data[i] = op(data[i<<1],data[i<<1|1]);
  }
  void update(int l,int r,F x){
    x = (x+1000)%4;
    update(l,r,x,1,0,N);
  }
  int query(int l,int r){
    S res = query(l,r,1,0,N);
    return res[0]-res[2];
  }
};
int main(){
  cin.tie(0);ios::sync_with_stdio(false);
  int N,M;cin >> N >> M;
  lazysegtree seg(N);
  while(M--){
    int t;cin >> t;
    if(t == 1){
      int a,b,c;cin >> a >> b >> c;a--;b--;
      seg.update(a,b+1,c);
    }
    else{
      int d,e;cin >> d >> e;d--;e--;
      cout << seg.query(d,e+1) << "\n";
    }
  }
}
accuracy: 1
time_ms: 90
memory_kb: 23664
final_rank: 5

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001



#define SIZE 300005

enum DIR{
	North,
	West,
	South,
	East,
};

struct NA{
	NA(){

		for(int i = 0; i < 4; i++){

			value[i] = 0;
		}
	}
	NA(ll arg_value[4]){

		for(int i = 0; i < 4; i++){

			value[i] = arg_value[i];
		}
	}
	ll value[4];
};

int N = 1;
int table[6*SIZE];
NA ans[6*SIZE];


void init(int first_N){
	while(N < first_N)N *= 2;
}

void first_add(int loc){

	loc += N-1;

	ans[loc].value[North] = 1;

	if(N == 1)return;

	int parent = (loc-1)/2;

	while(true){
		ans[parent].value[North] = ans[2*parent+1].value[North]+ans[2*parent+2].value[North];

		if(parent == 0)break;
		else{
			parent = (parent-1)/2;
		}
	}
}


void update(int update_left,int update_right,ll move,int node_id,int node_left,int node_right){

	if(update_right < node_left || update_left > node_right)return;

	if(update_left <= node_left && update_right >= node_right){

		int work[4];
		for(int i = 0; i < 4; i++){

			work[(i+move)%4] = ans[node_id].value[i];
		}
		for(int i = 0; i < 4; i++){

			ans[node_id].value[i] = work[i];
		}

		table[node_id] += move;

		return;

	}else{

		if(table[node_id] > 0){ //蓄積分

			update(node_left,node_right,table[node_id],2*node_id+1,node_left,(node_left+node_right)/2);
			update(node_left,node_right,table[node_id],2*node_id+2,(node_left+node_right)/2+1,node_right);

			table[node_id] = 0;
		}

		int L = 2*node_id+1,R = 2*node_id+2;

		update(update_left,update_right,move,2*node_id+1,node_left,(node_left+node_right)/2);
		update(update_left,update_right,move,2*node_id+2,(node_left+node_right)/2+1,node_right);

		//個数を再計算
		for(int i = 0; i < 4; i++){

			ans[node_id].value[i] = ans[L].value[i]+ans[R].value[i];
		}
	}
}

vector<int> query(int search_left,int search_right,int node_id,int node_left,int node_right){

	vector<int> ret;

	if(search_right < node_left || search_left > node_right){

		for(int i = 0; i < 4; i++){

			ret.push_back(0);
		}

		return ret;
	}

	if(search_left <= node_left && search_right >= node_right){


		for(int i = 0; i < 4; i++){

			ret.push_back(ans[node_id].value[i]);
		}

		return ret;


	}else{

		if(table[node_id] > 0){ //蓄積分

			update(node_left,node_right,table[node_id],2*node_id+1,node_left,(node_left+node_right)/2);
			update(node_left,node_right,table[node_id],2*node_id+2,(node_left+node_right)/2+1,node_right);

			table[node_id] = 0;
		}

		vector<int> vec_L = query(search_left,search_right,2*node_id+1,node_left,(node_left+node_right)/2);
		vector<int> vec_R = query(search_left,search_right,2*node_id+2,(node_left+node_right)/2+1,node_right);


		for(int i = 0; i < 4; i++){

			ret.push_back(vec_L[i]+vec_R[i]);
		}

		return ret;
	}
}


int main(){

	int first_N,Q;
	scanf("%d %d",&first_N,&Q);

	init(first_N);

	//printf("N:%d\n",N);

	for(int i = 0; i <= 2*N-2; i++){
		for(int a = 0; a < 4; a++){

			ans[i].value[a] = 0;
		}
	}
	for(int i = 0; i < first_N; i++){

		first_add(i);
	}

	int command;
	int left,right;
	int move;

	for(int i = 0; i < Q; i++){

		scanf("%d %d %d",&command,&left,&right);
		left--;
		right--;

		if(command == 1){ //回転命令

			scanf("%d",&move);

			if(move < 0){

				move = -((abs(move)%4));
				move += 4;
				move %= 4;

			}else{

				move %= 4;
			}

			if(move == 0)continue;

			update(left,right,move,0,0,N-1);

		}else{ //出力命令

			vector<int> ret = query(left,right,0,0,N-1);

			int to_N = ret[North];
			int to_S = ret[South];

			printf("%d\n",to_N-to_S);
		}
	}

	return 0;
}
accuracy: 1
time_ms: 370
memory_kb: 64992
final_rank: 18