Problem:
Moving Mass Game
Students at Idua High School are practicing the moving mass game in preparation for next year's sports festival. In this mass game, the students move and turn their bodies in accordance with the teacher's commands.
In the moving mass game, the teacher gives instructions to the students in the compartments numbered from $1$ to $N$. The compartments are lined up in a row from west to east, starting from 1. Initially, each student is in one of the compartments, all standing facing north. Each compartment is large enough to hold all the students. The teacher tells the students who are in which compartment at the time of instruction and how much they will move.
When the teacher shouts out the three numbers $a,b,c$, all the students in the compartments from $a$th to $b$th at that point move in a simultaneous manner according to the value of $c$, and also change their body orientation 180 degrees. If $c$ is a positive integer, the student moves east, if negative, the student moves west, and so on for one compartment per number size, and students who were facing north before the move will face south after the move, and students who were facing south will face north. In this case, students who are instructed to move to a compartment numbered less than $a$th will move to the $a$th compartment, and students who are instructed to move to a compartment numbered greater than $b$th will move to the $b$th compartment. This means that some students may not move at all, even if they are in the $a$th through $b$th compartments, but even these students will always change their body orientation 180 degrees.
The teacher giving the instructions believes that the orientation of the students at a given point in time has something to do with the beauty of the moving mass game. Therefore, he wants to know the number of students facing north minus the number of students facing south in the specified range of compartments immediately after the instruction at some point.
Given the number of compartments, the number of students, the number of the first compartment each student is in, and the information about the query to find the difference between the teacher's call and the number of students, for each query, write a program to find the number of students in the specified range of compartments facing north minus the number of students facing south.
Input
The input is given in the following format.
$N$ $M$
$x_1$
$x_2$
:
$x_M$
$Q$
$info_1$
$info_2$
 :
$info_Q$
The first line gives the number of compartments $N$ ($2 \leq N \leq 10^9=10$ to the $9$ power) and the number of students $M$ ($1 \leq M \leq 100,000$). In the next $M$ line, the number $x_i$ ($1 \leq x_i \leq N$) of the first compartment where the $i$th student is located is given. The next line is given the number $Q$ ($1 \leq Q \leq 100,000$) of information about the order and query. The subsequent $Q$ line gives the information $info_i$ about the order and query. The information is arranged in chrono
...(truncated)

Submitted solutions:

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

#define rep(i,n) for(int i=0;i<(n);i++)
#define rng(i,l,r) for(int i=(l);i<(r);i++)
#define rrep(i,n) for(int i=(n)-1;i>=0;i--)
#define rrng(i,l,r) for(int i=(r)-1;i>=(l);i--)
#define int long long
#define fi first
#define se second
#define pb push_back
#define all(x) (x).begin(),(x).end()
#define chmin(a,b) a=min(a,b)
#define chmax(a,b) a=max(a,b)


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,lg;
	vector<S> d;
	vector<F> lz;

	void pushup(int k){
		d[k]=op(d[k<<1],d[k<<1|1]);
	}
	void all_apply(int k,F f){
		d[k]=mapping(f,d[k]);
		if(k<sz)lz[k]=composition(f,lz[k]);
	}
	void pushdown(int k){
		all_apply(k<<1,lz[k]);
		all_apply(k<<1|1,lz[k]);
		lz[k]=id();
	}

	lazy_segtree():lazy_segtree(0){}
	explicit lazy_segtree(int n):lazy_segtree(vector<S>(n,e())){}
	explicit lazy_segtree(vector<S>v):n(v.size()){
		sz=1;lg=0;while(sz<n)sz<<=1,lg++;
		d=vector<S>(2*sz,e()),lz=vector<F>(2*sz,id());
		for(int i=0;i<n;i++)d[sz+i]=v[i];
		for(int i=sz-1;i>0;i--)pushup(i);
	}

	void set(int p,S x){
		p+=sz;
		for(int i=lg;i>=1;i--)pushdown(p>>i);
		d[p]=x;
		for(int i=1;i<=lg;i++)pushup(p>>i);
	}

	S get(int p){
		p+=sz;
		for(int i=lg;i>=1;i--)pushdown(p>>i);
		return d[p];
	}

	S prod(int l,int r){
		if(l==r)return e();
		l+=sz,r+=sz;
		for(int i=lg;i>=1;i--){
			pushdown(l>>i),pushdown((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);
	}

	void apply(int l,int r,F f){
		if(l==r)return;
		l+=sz,r+=sz;
		for(int i=lg;i>=1;i--){
			pushdown(l>>i);
			pushdown((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<=lg;i++){
			pushdown(l>>i),pushdown((r-1)>>i);
			pushup(l>>i),pushup((r-1)>>i);
		}
	}
};


using P=pair<int,int>;

int op(int a,int b){return a+b;}
int e(){return 0;}

int mapping(P f,int x){
	return f.fi*x+f.se;
}

P composition(P f,P g){
	return {f.fi*g.fi,f.se+f.fi*g.se};
}

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

signed main(){
	int M,N;cin>>M>>N;
	vector<int> X(N);for(auto&&e:X)cin>>e;
	sort(all(X));
	
	lazy_segtree<int,op,e,P,mapping,composition,id> seg1(X),seg2(vector<int>(N,1));
	
	auto lob=[&](int x)->int {
		int ok=-1,ng=N;
		while(abs(ok-ng)>1){
			int mid=(ok+ng)>>1;
			if(seg1.get(mid)<x)ok=mid;
			else ng=mid;
		}
		return ok+1;
	};
	
	int Q;cin>>Q;
	
	while(Q--){
		int t;cin>>t;
		
		if(t==1){
			int a,b,c;cin>>a>>b>>c;
			seg2.apply(lob(a),lob(b+1),{-1,0});
		//	cout<<"lr : "<<lob(a)<<" "<<lob(b)<<"\n";
			if(c<0){
				c=-c;
				
				if(a+c<b){
					int u=lob(a),v=lob(a+c),w=lob(b+1);
					seg1.apply(u,v,{0,a});
					seg1.apply(v,w,{1,-c});
					
				}else{
					seg1.apply(lob(a),lob(b+1),{0,a});
				}
			}else{
				if(a<b-c){
					int u=lob(b-c),v=lob(b+1),w=lob(a);
					seg1.apply(u,v,{0,b});
						seg1.apply(w,u,{1,c});
				}else{
					seg1.apply(lob(a),lob(b+1),{0,b});
				}
			}
		}else{
			int l,r;cin>>l>>r;
			cout<<seg2.prod(lob(l),lob(r+1))<<"\n";
		}
		
		//cout<<"A : ";rep(i,N)cout<<seg1.get(i)<<" ";cout<<"\n";
		//cout<<"B : ";rep(i,N)cout<<seg2.get(i)<<" ";cout<<"\n";
	}
}
accuracy: 1
time_ms: 580
memory_kb: 16964
final_rank: 11

code_snippet: #include <algorithm>
#include <iostream>
#include <cassert>
#include <functional>
#include <vector>

#define REP(i,s,n) for(int i=(int)(s);i<(int)(n);i++)

using namespace std;

// https://github.com/atcoder/ac-library/blob/v1.6/atcoder/internal_bit.hpp
unsigned int bit_ceil(unsigned int n) {
    unsigned int x = 1;
    while (x < (unsigned int)(n)) x *= 2;
    return x;
}

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

// https://github.com/atcoder/ac-library/blob/v1.6/atcoder/lazysegtree.hpp
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((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();
    }
};

// add-sum
struct S1 {
    int a;
    int size;
};

struct F1 {
    int a, b;
};

S1 op1(S1 l, S1 r) { return S1{l.a + r.a, l.size + r.size}; }

S1 e1() { return S1{0, 0}; }

S1 mapping1(F1 l, S1 r) { return S1{r.a * l.a + r.size * l.b, r.size}; }

F1 composition1(F1 l, F1 r) { return F1{r.a * l.a, r.b * l.a + l.b}; }

F1 id1() { return F1{1, 0}; }

// add-max
struct S2 {
    int a;
};

struct F2 {
    int coef; // 0 or 1
    int a;
};

S2 op2(S2 l, S2 r) { return S2{max(l.a, r.a)}; }

S2 e2() { return S2{-1}; }

S2 mapping2(F2 l, S2 r) { return S2{l.a + l.coef * r.a}; }

F2 composition2(F2 l, F2 r) { return F2{l.coef * r.coef, l.a + l.coef * r.a}; }

F2 id2() { return F2{1, 0}; }

int main() {
    int n, m;
    cin >> n >> m;
    vector<int> x(m);
    REP(i, 0, m) cin >> x[i];
    sort(x.begin(), x.end());
    vector<S2> t(m);
    REP(i, 0, m) t[i] = S2{x[i]};
    vector<S1> up(m);
    REP(i, 0, m) up[i] = S1{1, 1};
    lazy_segtree<S1, op1, e1, F1, mapping1, composition1, id1> seg1(up);
    lazy_segtree<S2, op2, e2, F2, mapping2, composition2, id2> seg2(t);
    int q;
    cin >> q;
    REP(_, 0, q) {
        int ty, a, b;
        cin >> ty >> a >> b;
        b++;
        if (ty == 1) {
            int c;
            cin >> c;
            if (c > 0) {
                int idx0 = seg2.max_right(0, [&](S2 val) { return val.a < a; });
                int idx1 = seg2.max_right(0, [&](S2 val) { return val.a < max(0, b - c); });
                idx1 = max(idx1, idx0);
                int idx2 = seg2.max_right(0, [&](S2 val) { return val.a < b; });
                seg2.apply(idx0, idx1, F2{1, c});
                seg2.apply(idx1, idx2, F2{0, b - 1});
                seg1.apply(idx0, idx2, F1{-1, 0});
            } else {
                int idx0 = seg2.max_right(0, [&](S2 val) { return val.a < a; });
                int idx1 = seg2.max_right(0, [&](S2 val) { return val.a < a - c; });
                int idx2 = seg2.max_right(0, [&](S2 val) { return val.a < b; });
                idx1 = min(idx1, idx2);
                seg2.apply(idx1, idx2, F2{1, c});
                seg2.apply(idx0, idx1, F2{0, a});
                seg1.apply(idx0, idx2, F1{-1, 0});
            }
        } else {
            int idx0 = seg2.max_right(0, [&](S2 val) { return val.a < a; });
            int idx1 = seg2.max_right(0, [&](S2 val) { return val.a < b; });
            auto val = seg1.prod(idx0, idx1);
            cout << val.a << "\n";
        }
    }
}
accuracy: 1
time_ms: 170
memory_kb: 10112
final_rank: 2

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


template <class S,
          S (*op)(S, S),
          S (*e)(),
          class F,
          S (*mapping)(F, S),
          F (*composition)(F, F),
          F (*id)()>
struct LazySegmentTree {
  private:
    int _n, size, log;
    vector<S> dat;
    vector<F> lz;
    void update(int k) { dat[k] = op(dat[2 * k], dat[2 * k + 1]); }
    void all_apply(int k, F f) {
        dat[k] = mapping(f, dat[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();
    }
    int lower_bits(int x, int k) { return x & ((1 << k) - 1); }

  public:
    LazySegmentTree() : LazySegmentTree(0) {}
    LazySegmentTree(int n) : LazySegmentTree(vector<S>(n, e())) {}
    LazySegmentTree(const vector<S>& v) : _n(int(v.size())) {
        log = 0;
        while ((1 << log) < _n) log++;
        size = 1 << log;
        dat = vector<S>(2 * size, e());
        lz = vector<F>(size, id());
        for (int i = 0; i < _n; i++) dat[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) update(i);
    }
    // a[p] = x
    void set(int p, S x) {
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        dat[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }
    // return a[p]
    S get(int p) {
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        return dat[p];
    }
    // return op(a[l], ..., a[r-1])
    S prod(int l, int r) {
        if (l == r) return e();
        l += size;
        r += size;
        for (int i = log; i >= 1; i--) {
            if (lower_bits(l, i) > 0) push(l >> i);
            if (lower_bits(r, i) > 0) push((r - 1) >> i);
        }
        S sml = e(), smr = e();
        while (l < r) {
            if (l & 1) sml = op(sml, dat[l++]);
            if (r & 1) smr = op(dat[--r], smr);
            l >>= 1;
            r >>= 1;
        }
        return op(sml, smr);
    }
    S all_prod() { return dat[1]; }
    // a[p] = f(a[p])
    void apply(int p, F f) {
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        dat[p] = mapping(f, dat[p]);
        for (int i = 1; i <= log; i++) update(p >> i);
    }
    // i = l...r-1 について a[i] = f(a[i])
    void apply(int l, int r, F f) {
        if (l == r) return;
        l += size;
        r += size;
        for (int i = log; i >= 1; i--) {
            if (lower_bits(l, i) > 0) push(l >> i);
            if (lower_bits(r, i) > 0) 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 (lower_bits(l, i) > 0) update(l >> i);
            if (lower_bits(r, i) > 0) update((r - 1) >> i);
        }
    }
    // SegmentTree上の二分探索 (必要な場合)
    // return r, f(op(a[l], ..., a[r-1])) == true
    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(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, dat[l]))) {
                while (l < size) {
                    push(l);
                    l = (2 * l);
                    if (g(op(sm, dat[l]))) {
                        sm = op(sm, dat[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, dat[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }
    // return l, f(op(a[l], ..., a[r-1])) == true
    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(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(dat[r], sm))) {
                while (r < size) {
                    push(r);
                    r = (2 * r + 1);
                    if (g(op(dat[r], sm))) {
                        sm = op(dat[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(dat[r], sm);
        } while ((r & -r) != r);
        return 0;
    }
};


struct S{
    ll x, d, d1;
};

S op(S a, S b){
    return S{a.x+b.x, a.d+b.d, a.d1+b.d1};
}

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

struct F{
    ll d, a, c;
};

S mapping(F f, S s){
    if(f.d==1) s.d1 = s.d-s.d1;
    if(f.c==-1){
        s.x += f.a;
    }
    else{
        s.x = f.c;
    }
    return s;
}

F composition(F f, F g){
    F res = F{0,0,-1};
    res.d = f.d ^ g.d;
    if(f.c==-1){
        if(g.c==-1){
            res.a = f.a+g.a;
        }
        else{
            res.c = g.c+f.a;
        }
    }
    else{
        if(g.c==-1){
            res.c = f.c;
        }
        else{
            res.c = f.c;
        }
    }

    return res;
}

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

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    int N,M;
    cin >> N >> M;
    vector<ll> X(M);
    rep(i,M) cin >> X[i];
    sort(X.begin(),X.end());
    vector<S> ini(M);
    rep(i,M) ini[i] = S{X[i], 1, 0};
    
    LazySegmentTree<S,op,e,F,mapping,composition,id> seg(ini);

    auto nibutan = [&](ll x) -> int {
        int ok = M;
        int ng = -1;
        while(abs(ok-ng)>1){
            int mid = (ok+ng)/2;
            if(seg.get(mid).x>x) ok = mid;
            else ng = mid;
        }
        return ok;
    };

    int Q;
    cin >> Q;
    rep(qi,Q){
        int t;
        cin >> t;
        if(t==1){
            int a,b,c;
            cin >> a >> b >> c;

            int L = nibutan(a-1);
            int R = nibutan(b);
            // cout << L <<  " " << R << endl;
            seg.apply(L, R, F{1, 0, -1});

            if(c<0){
                int C = nibutan(a-c);
                C = min(C,R);
                seg.apply(L,C, F{0,0,a});
                seg.apply(C,R, F{0,c,-1});
            }
            if(c>0){
                int C = nibutan(b-c);
                C = max(C,L);
                seg.apply(L,C, F{0,c,-1});
                seg.apply(C,R, F{0,0,b});
            }

            // rep(j,M) cout << seg.get(j).x << " ";
            // cout << ";" << endl;
        }
        else{
            int d,e;
            cin >> d >> e;
            int L = nibutan(d-1);
            int R = nibutan(e);
            // cout << L << ' ' << R << endl;
            cout << seg.prod(L,R).d-seg.prod(L,R).d1*2 << "\n";
        }
    }

}
accuracy: 1
time_ms: 550
memory_kb: 15556
final_rank: 8

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




namespace zawa {

using i16 = std::int16_t;
using i32 = std::int32_t;
using i64 = std::int64_t;
using i128 = __int128_t;

using u8 = std::uint8_t;
using u16 = std::uint16_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;

using usize = std::size_t;

} // namespace zawa


namespace zawa {

void SetFastIO() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
}

void SetPrecision(u32 dig) {
    std::cout << std::fixed << std::setprecision(dig);
}

} // namespace zawa




namespace zawa {

template <class Monoid>
class CommutativeDualSegmentTree {
public:
    using Operator = typename Monoid::Element;
protected:

    static constexpr u32 parent(u32 v) noexcept {
        return v >> 1;
    }
    static constexpr u32 left(u32 v) noexcept {
        return v << 1;
    }
    static constexpr u32 right(u32 v) noexcept {
        return v << 1 | 1;
    }

    usize n_;
    std::vector<Operator> dat_;

    template <class InputIterator>
    inline void initDat(InputIterator first, InputIterator last) {
        for (auto it{ first } ; it != last ; it++) {
            dat_[n_ + std::distance(first, it)] = *it;
        }
    }

    void push(u32 i) {
        assert(i < n_);
        i += n_;
        u32 height{ 32u - __builtin_clz(i) };
        for (u32 h{ height } ; --h ; ) {
            u32 v{ i >> h };
            dat_[left(v)] = Monoid::operation(dat_[left(v)], dat_[v]);
            dat_[right(v)] = Monoid::operation(dat_[right(v)], dat_[v]);
            dat_[v] = Monoid::identity();
        }
    }

public:
    CommutativeDualSegmentTree() = default;
    CommutativeDualSegmentTree(usize n) 
        : n_{ n }, dat_((n << 1), Monoid::identity()) {}
    CommutativeDualSegmentTree(const std::vector<Operator>& dat) 
        : n_{ dat.size() }, dat_((n_ << 1), Monoid::identity()) {
        initDat(dat.begin(), dat.end());
    }
    template <class InputIterator>
    CommutativeDualSegmentTree(InputIterator first, InputIterator last)
        : n_{ static_cast<usize>(std::distance(first, last)) }, dat_((n_ << 1), Monoid::identity()) {
        initDat(first, last);
    }

    virtual void operation(u32 l, u32 r, const Operator& v) {
        assert(l < n_);
        assert(l <= r and r <= n_);
        for (l += n_, r += n_ ; l < r ; l = parent(l), r = parent(r)) {
            if (l & 1) {
                dat_[l] = Monoid::operation(dat_[l], v);
                l++;
            }
            if (r & 1) {
                r--;
                dat_[r] = Monoid::operation(dat_[r], v);
            }
        }
    }

    void set(u32 i, const Operator& v) {
        assert(i < n_);
        push(i);
        dat_[i + n_] = v;
    }

    virtual Operator operator[](u32 i) {
        assert(i < n_);
        Operator res{ Monoid::identity() };
        for (i += n_ ; i ; i = parent(i)) {
            res = Monoid::operation(res, dat_[i]);
        }
        return res;
    }

    friend std::ostream& operator<<(std::ostream& os, const CommutativeDualSegmentTree seg) {
        usize size{ seg.dat_.size() };
        for (u32 i{1} ; i < size ; i++) {
            os << seg.dat_[i] << (i + 1 == size ? "" : " ");
        }
        return os;
    }
};

} // namespace zawa

namespace zawa {

template <class Monoid>
class DualSegmentTree : public CommutativeDualSegmentTree<Monoid> {
private:
    using Base = CommutativeDualSegmentTree<Monoid>;
public:
    using Operator = typename Base::Operator;
    DualSegmentTree() : Base() {}
    DualSegmentTree(u32 n) : Base(n) {}
    DualSegmentTree(const std::vector<Operator>& dat) : Base(dat) {}
    template <class InputIterator>
    DualSegmentTree(InputIterator first, InputIterator last) : Base(first, last) {}
    
    void operation(u32 l, u32 r, const Operator& v) override {
        Base::push(l);
        if (l < r) Base::push(r - 1);
        Base::operation(l, r, v);
    } 

    Operator operator[](u32 i) override {
        Base::push(i);
        return Base::operator[](i);
    }
};

} // namespace zawa




namespace zawa {

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

    // ノードvの子に作用を伝播させる
    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();
    }

    // ノードvの祖先のノードの作用素を全て適用する
    void propagateAncestor(u32 v) {
        u32 dep{depth(v)};
        u32 zeros{trailingZeros(v)};
        for (u32 d{dep} ; d != zeros ; d--) {
            propagate(v >> d);
        }
    }

    // ノードvの値を再計算する
    void recalc(u32 v) {
        dat_[v].v_ = VM::operation(action(dat_[left(v)]), action(dat_[right(v)]));
    }

    // 要素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());
    }
    template <class InputIterator>
    LazySegmentTree(InputIterator first, InputIterator last) 
        : n_{static_cast<usize>(std::distance(first, last))}, dat_(std::distance(first, last) << 1) {
        assert(n_);
        datInit(first);
    }

    usize size() const noexcept {
        return n_;
    }

    void operation(u32 i, const Operator& o) {
        assert(i < n_);
        i += size();
        propagateAncestor(i);
        dat_[i].o_ = OM::operation(dat_[i].o_, o);
        recalcAncestor(i);
    }

    void operation(u32 L, u32 R, const Operator& o) {
        assert(L < n_);
        assert(L <= R 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);
    }

    void set(u32 i, const Value& v) {
        assert(i < n_);
        i += size();
        for (u32 d{depth(i)} ; d ; d--) {
            propagate(i >> d);
        }
        dat_[i] = Node{ v, OM::identity() };
        for (i = parent(i) ; i ; i = parent(i)) {
            recalc(i);
        }
    }

    Value operator[](u32 i) {
        assert(i < n_);
        i += size();
        for (u32 d{depth(i)} ; d ; d--) {
            propagate(i >> d);
        }
        return action(dat_[i]);
    }

    Value product(u32 L, u32 R) {
        assert(L < n_);
        assert(L <= R 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);
    }

    friend std::ostream& operator<<(std::ostream& os, const LazySegmentTree& seg) {
        usize size{seg.dat_.size()};
        os << "Value :\n";
        for (u32 i{1} ; i < size ; i++) {
            os << seg.dat_[i].v_ << (i + 1 == size ? "\n" : " ");
        }
        os << "Operator :\n";
        for (u32 i{1} ; i < size ; i++) {
            os << seg.dat_[i].o_ << (i + 1 == size ? "\n" : " ");
        }
        os << "Action :\n";
        for (u32 i{1} ; i < size ; i++) {
            os << action(seg.dat_[i]) << (i + 1 == size ? "\n" : " ");
        }
        return os;
    }

/*
    template <class F>
    u32 maxRight(u32 l, const F& f) {

    }

    template <class F>
    u32 minLeft(u32 r, const F& f) {

    }
*/
};

} // namespace zawa


#include <type_traits>

namespace zawa {

namespace internal {

template <class T>
T MidPoint(T a, T b) {
    if (a > b) std::swap(a, b);
    return a + ((b - a) >> 1);
}

template <class T>
T Abs(T a, T b) {
    return (a >= b ? a - b : b - a);
}

} // namespace zawa::internal

template <class T, class Function>
T BinarySearch(T ok, T ng, const Function& f) {
    static_assert(std::is_integral_v<T>, "T must be integral type");
    static_assert(std::is_convertible_v<Function, std::function<bool(T)>>, "f must be function bool(T)");
    while (internal::Abs(ok, ng) > 1) {
        T mid{ internal::MidPoint(ok, ng) };
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template <class T, class Function>
T BinarySearch(T ok, T ng, const Function& f, u32 upperLimit) {
    static_assert(std::is_signed_v<T>, "T must be signed arithmetic type");
    static_assert(std::is_convertible_v<Function, std::function<bool(T)>>, "f must be function bool(T)");
    for (u32 _{} ; _ < upperLimit ; _++) {
        T mid{ (ok + ng) / (T)2 };
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

} // namespace zawa
using namespace zawa;

// lazyseg
struct VM {
    using Element = int;
    static Element identity() {
        return 0;
    }
    static Element operation(Element a, Element b) {
        return a + b;
    }
};
struct OM {
    using Element = bool;
    static Element identity() {
        return false;
    }
    static Element operation(Element a, Element b) {
        return a ^ b;
    }
};
struct S {
    using ValueMonoid = VM;
    using OperatorMonoid = OM;
    static VM::Element mapping(VM::Element v, OM::Element o) {
        return (o ? -v : v);
    }
};

// dualseg
struct OM2 {
    using Element = std::pair<int, int>;
    static Element identity() {
        return { -1, 0 };
    }
    static Element operation(Element A, Element B) {
        if (B.first != -1) return B;
        if (A.first != -1) return { A.first + B.second, 0 };
        return { -1, A.second + B.second };
    }
};
std::ostream& operator<<(std::ostream& os, const std::pair<int, int>& p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
int eval(const OM2::Element& p) {
    return (p.first != -1 ? p.first + p.second : p.second);
}

int main() {
    SetFastIO();

    int N, M;
    std::cin >> N >> M;
    std::vector<OM2::Element> x(M);
    for (auto& v : x) {
        v.first = -1;
        std::cin >> v.second;
    }
    std::sort(x.begin(), x.end());
    int Q;
    std::cin >> Q;
    LazySegmentTree<S> ls{std::vector<VM::Element>(M, 1)};
    DualSegmentTree<OM2> ds{x};
    auto idx{[&](int i) -> int {
        if (eval(ds[M - 1]) < i) return M;
        return BinarySearch(M - 1, -1, [&](int j) -> bool { return eval(ds[j]) >= i; });
    }};
    // for (auto v : x) std::cout << eval(v) << ' ';
    // std::cout << std::endl;
    while (Q--) {
        int t;
        std::cin >> t;
        if (t == 1) {
            int a, b, c;
            std::cin >> a >> b >> c;
            // std::cout << "operation " << a << ' ' << b << ' ' << c << std::endl;
            int L{idx(a)}, R{idx(b + 1)};
            // std::cout << L << ' ' << R << std::endl;
            if (L < M) ls.operation(L, R, true);
            if (c < 0) {
                int mid{idx(a - c + 1)};
                mid = std::min(mid, R);
                if (L < M) ds.operation(L, mid, { a, 0 });
                if (mid < R) ds.operation(mid, R, { -1, c });
            }
            else {
                int mid{idx(b - c)};
                mid = std::max(mid, L);
                if (L < M) ds.operation(L, mid, { -1, c });
                if (mid < R) ds.operation(mid, R, { b, 0 });
            }
        }
        else if (t == 2) {
            int d, e;
            std::cin >> d >> e;
            int L{idx(d)}, R{idx(e + 1)}; 
            // std::cout << d << ' ' << e << std::endl;
            // std::cout << L << ' ' << R << std::endl;
            if (L < M) std::cout << ls.product(L, R) << '\n';
            else std::cout << 0 << '\n';
        }
        else {
            assert(false);
        }
        // std::cout << ds << '\n';
        // for (int i{} ; i < M ; i++) {
        //     std::cout << eval(ds[i]) << ' ';
        // }
        // std::cout << std::endl;
        // std::cout << "------------------" << std::endl;
    }
}
accuracy: 1
time_ms: 350
memory_kb: 6912
final_rank: 6

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

constexpr int NONE = -1;
constexpr int ADD = 0;
constexpr int UPDATE = 1;

struct Data {
    int type;
    int value;
    Data(int t = NONE, int v = 0): type(t), value(v) {}
    int eval(int x) {
        if (type == NONE) return x;
        else if (type == UPDATE) return value;
        else return x + value;
    }
};

Data merge(Data lhs, Data rhs) {
    if (lhs.type < rhs.type) return rhs;
    if (rhs.type == UPDATE) return rhs;
    if (lhs.type == UPDATE) return Data(UPDATE, lhs.value + rhs.value);
    return Data(ADD, lhs.value + rhs.value);
}

int main() {
    {int n; std::cin >> n;}
    int n;
    std::cin >> n;
    std::vector<int> x(n);
    for (int i = 0; i < n; i++) std::cin >> x[i];
    std::sort(x.begin(), x.end());

    // direction
    const int NORTH = 1;
    const int SOUTH = -1;
    std::vector<int> direction(n, NORTH);

    // bucket
    const int B = 300;
    const int BUCKET_NUM = (n + B - 1) / B;
    std::vector<Data> ope(BUCKET_NUM);
    std::vector<int> sum(BUCKET_NUM);
    std::vector<int> reverse(BUCKET_NUM);
    for (int left = 0; left < n; left += B) {
        int right = std::min(left + B, n);
        sum[left / B] = right - left;
    }

    auto lower = [&](int pos) {
        int ok = n;
        int ng = -1;
        while (ok - ng > 1) {
            int key = (ok + ng) / 2;
            if (pos <= ope[key / B].eval(x[key])) {
                ok = key;
            } else {
                ng = key;
            }
        }
        return ok;
    };
    auto upper = [&](int pos) {
        return lower(pos + 1);
    };

    auto eval = [&](int bucket_i) {
        const int offset = bucket_i * B;
        for (int i = 0; i < B && offset + i < n; i++) {
            x[offset + i] = ope[bucket_i].eval(x[offset + i]);
        }
        ope[bucket_i] = Data();
        // assert(std::is_sorted(x.begin() + offset, x.begin() + std::min(offset + B, n)));
        if (reverse[bucket_i]) {
            reverse[bucket_i] = 0;
            for (int i = 0; i < B && offset + i < n; i++) {
                direction[i + offset] *= -1;
            }
        }
        sum[bucket_i] = 0;
        for (int i = 0; i < B && offset + i < n; i++) {
            sum[bucket_i] += direction[i + offset];
        }
    };

    auto query = [&](int left, int right, Data data) {
        if (left % B != 0) {
            eval(left / B);
            for (; left % B != 0 && left < right; left++) {
                x[left] = data.eval(x[left]);
                sum[left / B] -= direction[left];
                direction[left] *= -1;
                sum[left / B] += direction[left];
            }
        }
        if (right % B != 0) {
            eval(right / B);
            for (; right % B != 0 && left < right; ) {
                right--;
                x[right] = data.eval(x[right]);
                sum[right / B] -= direction[right];
                direction[right] *= -1;
                sum[right / B] += direction[right];
            }
        }
        assert(left == right || (left % B == 0 && right % B == 0));
        for (; left < right; left += B) {
            const int bucket_i = left / B;
            ope[bucket_i] = merge(ope[bucket_i], data);
            reverse[bucket_i] ^= 1;
            sum[bucket_i] *= -1;
        }
    };
    auto add = [&](int left, int right, int diff) {
        query(left, right, Data(ADD, diff));
    };
    auto update = [&](int left, int right, int value) {
        query(left, right, Data(UPDATE, value));
    };

    int q;
    std::cin >> q;
    while (q--) {
        int t;
        std::cin >> t;
        if (t == 1) {
            int a, b, c;
            std::cin >> a >> b >> c;
            int left = lower(a);
            int right = upper(b);
            if (c >= 0) {
                int mid = std::max(left, lower(b - c));
                add(left, mid, c);
                update(mid, right, b);
            } else {
                int mid = std::min(right, lower(a - c));
                update(left, mid, a);
                add(mid, right, c);
            }
        } else {
            int d, e;
            std::cin >> d >> e;
            int left = lower(d);
            int right = upper(e);
            int ans = 0;
            if (left % B != 0) {
                eval(left / B);
                for (; left % B != 0 && left < right; left++) {
                    ans += direction[left];
                }
            }
            if (right % B != 0) {
                eval(right / B);
                for (; right % B != 0 && left < right; ) {
                    right--;
                    ans += direction[right];
                }
            }
            assert(left == right || (left % B == 0 && right % B == 0));
            for (; left < right; left += B) {
                const int bucket_i = left / B;
                ans += sum[bucket_i];
            }
            std::cout << ans << '\n';
        }
        // for (int i = 0; i < BUCKET_NUM; i++) {
        //     eval(i);
        // }
        // assert(std::is_sorted(x.begin(), x.end()));
        // for (int i = 0; i < n; i++) {
        //     std::cerr << x[i] << ' ';
        // }
        // std::cerr << std::endl;
    }
}
accuracy: 1
time_ms: 400
memory_kb: 3904
final_rank: 3

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

const int NONE = -1;
const int ADD = 0;
const int UPDATE = 1;
struct Data {
    Data(): type(NONE), value(0) {}
    Data(int t, int v): type(t), value(v) {}
    int type;
    int value;
    int eval(int v) {
        if (type == NONE) return v;
        else if (type == ADD) return v + value;
        else return value;
    }
};

Data merge(Data first, Data second) {
    if (first.type < second.type) {
        return second;
    } else if (first.type == ADD) {
        return Data(ADD, first.value + second.value);
    } else if (first.type == UPDATE) {
        return second;
    } else {
        return Data();
    }
}

struct Bucket {
    std::vector<int> x, dir;
    int sum;
    Data query;
    Bucket(std::vector<int>::iterator a, 
            std::vector<int>::iterator b)
        : x(a, b), 
          dir(x.size(), 1),
          sum(x.size()) {}
    void eval() {
        if (query.type == NONE) return;
        for (auto& v: x) v = query.eval(v);
        sum = 0;
        for (auto& v: dir) {
            sum -= v;
            v = -v;
            sum += v;
        }
        query = Data();
    }
    int size() {
        return x.size();
    }
    void all(int type, int v) {
        query = merge(query, Data(type, v));
        sum = -sum;
    }
    void partial(int type, int l, int r, int v) {
        assert(0 <= l && l <= (int)x.size());
        assert(l <= r && r <= (int)x.size());
        eval();
        if (type == ADD) {
            for (int i = l; i < r; i++) x[i] += v;
        } else {
            for (int i = l; i < r; i++) x[i] = v;
        }
        for (int i = l; i < r; i++) {
            sum -= dir[i];
            dir[i] = -dir[i];
            sum += dir[i];
        }
    }
    int get(int pos) {
        return query.eval(x.at(pos));
    }
    int beautiful() {
        return sum;
    }
    int beautiful(int l, int r) {
        assert(0 <= l && l <= (int)x.size());
        assert(l <= r && r <= (int)x.size());
        eval();
        int res = 0;
        for (int i = l; i < r; i++) res += dir[i];
        return res;
    }
};

int main() {
    int n, m;
    std::cin >> n >> m;
    std::vector<int> x(m);
    for (int i = 0; i < m; i++) std::cin >> x[i];
    std::sort(x.begin(), x.end());
    const int B = 300;
    const int D = (m + B - 1) / B;
    std::vector<Bucket> bucket;
    for (int i = 0; i < D; i++) {
        int left = i * B;
        int right = std::min(left + B, m);
        bucket.emplace_back(x.begin() + left, x.begin() + right);
    }

    // lower_bound
    auto lower = [&](int v) {
        int ok = m;
        int ng = -1;
        while (ok - ng > 1) {
            int key = (ok + ng) / 2;
            int bucket_i = key / B;
            int pos = key - (bucket_i * B);
            if (v <= bucket[bucket_i].get(pos)) {
                ok = key;
            } else {
                ng = key;
            }
        }
        return ok;
    };
    auto upper = [&](int v) {
        int ok = m;
        int ng = -1;
        while (ok - ng > 1) {
            int key = (ok + ng) / 2;
            int bucket_i = key / B;
            int pos = key - (bucket_i * B);
            if (v < bucket[bucket_i].get(pos)) {
                ok = key;
            } else {
                ng = key;
            }
        }
        return ok;
    };

    auto query = [&](int type, int left, int right, int value) {
        if (left % B != 0) {
            int bucket_i = left / B;
            bucket[bucket_i].partial(type, left % B, std::min(B, right - bucket_i * B), value);
            left = std::min((bucket_i + 1) * B, right);
        }
        if (right % B != 0) {
            int bucket_i = right / B;
            bucket[bucket_i].partial(type, std::max(0, left - bucket_i * B), right % B, value);
            right = std::max(left, bucket_i * B);
        }
        for (int i = left; i < right; i += B) {
            bucket[i / B].all(type, value);
        }
    };

    int q;
    std::cin >> q;
    while (q--) {
        int t;
        std::cin >> t;
        if (t == 1) {
            int a, b, c;
            std::cin >> a >> b >> c;
            int left = lower(a);
            int right = upper(b);
            if (c >= 0) {
                int mid = std::max(left, lower(b - c));
                // add [left, mid] c
                query(ADD, left, mid, c);
                // update [mid, right] b
                query(UPDATE, mid, right, b);
            } else {
                int mid = std::min(right, upper(a - c));
                // update [left, mid] a;
                query(UPDATE, left, mid, a);
                // add [mid, right] c;
                query(ADD, mid, right, c);
            }
        } else {
            int d, e;
            std::cin >> d >> e;
            int ans = 0;
            int left = lower(d);
            int right = upper(e);
            if (left % B != 0) {
                int bucket_i = left / B;
                ans += bucket[bucket_i].beautiful(left % B, std::min(B, right - bucket_i * B));
                left = std::min((bucket_i + 1) * B, right);
            }
            if (right % B != 0) {
                int bucket_i = right / B;
                ans += bucket[bucket_i].beautiful(std::max(0, left - bucket_i * B), right % B);
                right = std::max(left, bucket_i * B);
            }
            for (int i = left; i < right; i += B) {
                ans += bucket[i / B].beautiful();
            }
            std::cout << ans << '\n';
        }
    }
    // std::cerr << "bucket.size = " << bucket.size() << std::endl;
    // std::cerr << "bucket[0].size = " << bucket[0].size() << std::endl;
    // std::cerr << "bucket[0].beautiful = " << bucket[0].beautiful() << std::endl;
    // std::cerr << "bucket[0].beautiful = " << bucket[0].beautiful() << std::endl;
}
accuracy: 0.4583333333333333
time_ms: 10
memory_kb: 3448
final_rank: 14

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

const int NONE = -1;
const int ADD = 0;
const int UPDATE = 1;
struct Data {
    Data(): type(NONE), value(0) {}
    Data(int t, int v): type(t), value(v) {}
    int type;
    int value;
    int eval(int v) {
        if (type == NONE) return v;
        else if (type == ADD) return v + value;
        else return value;
    }
};

Data merge(Data first, Data second) {
    if (first.type < second.type) {
        return second;
    } else if (first.type == ADD) {
        return Data(ADD, first.value + second.value);
    } else if (first.type == UPDATE) {
        return second;
    } else {
        return Data();
    }
}

struct Bucket {
    std::vector<int> x, dir;
    int sum;
    Data query;
    Bucket(std::vector<int>::iterator a, 
            std::vector<int>::iterator b)
        : x(a, b), 
          dir(x.size(), 1),
          sum(x.size()) {}
    void eval() {
        if (query.type == NONE) return;
        for (auto& v: x) v = query.eval(v);
        sum = 0;
        for (auto& v: dir) {
            sum -= v;
            v = -v;
            sum += v;
        }
        query = Data();
    }
    int size() {
        return x.size();
    }
    void all(int type, int v) {
        query = merge(query, Data(type, v));
        sum = -sum;
    }
    void partial(int type, int l, int r, int v) {
        assert(0 <= l && l <= (int)x.size());
        assert(l <= r && r <= (int)x.size());
        eval();
        if (type == ADD) {
            for (int i = l; i < r; i++) x[i] += v;
        } else {
            for (int i = l; i < r; i++) x[i] = v;
        }
        for (int i = l; i < r; i++) {
            sum -= dir[i];
            dir[i] = -dir[i];
            sum += dir[i];
        }
    }
    int get(int pos) {
        return query.eval(x.at(pos));
    }
    int beautiful() {
        return sum;
    }
    int beautiful(int l, int r) {
        assert(0 <= l && l <= (int)x.size());
        assert(l <= r && r <= (int)x.size());
        eval();
        int res = 0;
        for (int i = l; i < r; i++) res += dir[i];
        return res;
    }
};

int main() {
    int n, m;
    std::cin >> n >> m;
    std::vector<int> x(m);
    for (int i = 0; i < m; i++) std::cin >> x[i];
    std::sort(x.begin(), x.end());
    const int B = 300;
    const int D = (m + B - 1) / B;
    std::vector<Bucket> bucket;
    for (int i = 0; i < D; i++) {
        int left = i * B;
        int right = std::min(left + B, m);
        bucket.emplace_back(x.begin() + left, x.begin() + right);
    }

    // lower_bound
    auto lower = [&](int v) {
        int ok = m;
        int ng = -1;
        while (ok - ng > 1) {
            int key = (ok + ng) / 2;
            int bucket_i = key / B;
            int pos = key - (bucket_i * B);
            if (v <= bucket[bucket_i].get(pos)) {
                ok = key;
            } else {
                ng = key;
            }
        }
        return ok;
    };
    auto upper = [&](int v) {
        int ok = m;
        int ng = -1;
        while (ok - ng > 1) {
            int key = (ok + ng) / 2;
            int bucket_i = key / B;
            int pos = key - (bucket_i * B);
            if (v < bucket[bucket_i].get(pos)) {
                ok = key;
            } else {
                ng = key;
            }
        }
        return ok;
    };

    auto query = [&](int type, int left, int right, int value) {
        if (left % B != 0) {
            int bucket_i = left / B;
            bucket[bucket_i].partial(type, left % B, std::min(B, right - bucket_i * B), value);
            left = std::min((bucket_i + 1) * B, right);
        }
        if (right % B != 0) {
            int bucket_i = right / B;
            bucket[bucket_i].partial(type, std::max(0, left - bucket_i * B), right % B, value);
            right = bucket_i * B;
        }
        for (int i = left; i < right; i += B) {
            bucket[i / B].all(type, value);
        }
    };

    int q;
    std::cin >> q;
    while (q--) {
        int t;
        std::cin >> t;
        if (t == 1) {
            int a, b, c;
            std::cin >> a >> b >> c;
            int left = lower(a);
            int right = upper(b);
            if (c >= 0) {
                int mid = std::max(left, lower(b - c));
                // add [left, mid] c
                query(ADD, left, mid, c);
                // update [mid, right] b
                query(UPDATE, mid, right, b);
            } else {
                int mid = std::min(right, upper(a - c));
                // update [left, mid] a;
                query(UPDATE, left, mid, a);
                // add [mid, right] c;
                query(ADD, mid, right, c);
            }
        } else {
            int d, e;
            std::cin >> d >> e;
            int ans = 0;
            int left = lower(d);
            int right = upper(e);
            if (left % B != 0) {
                int bucket_i = left / B;
                ans += bucket[bucket_i].beautiful(left % B, std::min(B, right - bucket_i * B));
                left = std::min((bucket_i + 1) * B, right);
            }
            if (right % B != 0) {
                int bucket_i = right / B;
                ans += bucket[bucket_i].beautiful(std::max(0, left - bucket_i * B), right % B);
                right = std::max(left, bucket_i * B);
            }
            for (int i = left; i < right; i += B) {
                ans += bucket[i / B].beautiful();
            }
            std::cout << ans << '\n';
        }
    }
    // std::cerr << "bucket.size = " << bucket.size() << std::endl;
    // std::cerr << "bucket[0].size = " << bucket[0].size() << std::endl;
    // std::cerr << "bucket[0].beautiful = " << bucket[0].beautiful() << std::endl;
    // std::cerr << "bucket[0].beautiful = " << bucket[0].beautiful() << std::endl;
}
accuracy: 0.4583333333333333
time_ms: 10
memory_kb: 3392
final_rank: 13

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

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

#define ll long long
// #define int long long

#define rep(i, n) for(int i=0; i<(n); ++i)

template<class T>
using vec = vector<T>;

struct StudentState {
  int l, r;
  int num;
  int north_sum;
  bool operator== (const StudentState &a) {
    return l == a.l && r == a.r && num == a.num && north_sum == a.north_sum;
  }
};
struct Function {
  bool mode; // 0 -> add, 1 -> set
  int val;
  int turn; // -1=反転(default)、1=そのまま
  bool operator== (const Function &f) {
    return mode == f.mode && val == f.val && turn == f.turn;
  }
};

// Lazy Segtree
struct LazySegmentTree {
  using T = StudentState;
  using F = Function;
  T e = {2000000000,2000000000,0,0};
  F id = {0, 0, 1};
  T op(T l, T r) {
    return {min(l.l, r.l), l.r == e.r ? r.r : r.r == e.r ? l.r : max(l.r, r.r), l.num + r.num, l.north_sum + r.north_sum};
  }
  T update(T val, F fn) {
    if(fn.mode == 0) {
      return {val.l+fn.val, val.r+fn.val, val.num, val.north_sum * fn.turn};
    } else {
      return {fn.val, fn.val, val.num, val.north_sum * fn.turn};
    }
  }
  F merge(F current, F append) {
    if(current.mode == 0 && append.mode == 0) {
      return {0, current.val + append.val, current.turn * append.turn};
    }
    if(current.mode == 0 && append.mode == 1) {
      return {1, append.val, current.turn * append.turn};
    }
    if(current.mode == 1 && append.mode == 0) {
      return {1, current.val + append.val, current.turn * append.turn};
    }
    if(current.mode == 1 && append.mode == 1) {
      return {1, append.val, current.turn * append.turn};
    }
    return id;
  }
  int _n;
  int _height;
  vec<T> _data;
  vec<F> _lazy;

  LazySegmentTree(int n) {
    _n = 1;
    while(_n < n) _n*=2;
    _data = vec<T>(_n*2, e);
    _lazy = vec<F>(_n*2, id);
  }
  void init(int i, T data){
    _data[i+_n] = data;
  }
  void build() {
    for(int i=_n-1; i>0; i--) {
      _data[i] = op(_data[i*2], _data[i*2+1]);
    }
  }
  void eval(int k) {
    if(_lazy[k] == id) return;
    _data[k] = update(_data[k], _lazy[k]);
    if(k < _n) {
      _lazy[k*2+0] = merge(_lazy[k*2+0], _lazy[k]);
      _lazy[k*2+1] = merge(_lazy[k*2+1], _lazy[k]);
    }
    _lazy[k] = id;
  }
  void set(int l, int r, F f) {
    int a = l + _n, b = r + _n - 1;
    for(int i = _height; i > 0; i--) eval(a>>i), eval(b>>i);
    for(b++; a<b; a>>=1, b>>=1) {
      if(a&1) _lazy[a] = merge(_lazy[a], f), eval(a), a++;
      if(b&1) --b, _lazy[b] = merge(_lazy[b], f), eval(b);
    }
    a = l + _n, b = r + _n - 1;
    while((a>>=1), (b>>=1), a) {
      if(_lazy[a] == id) _data[a] = op(
        update(_data[a*2+0], _lazy[a*2+0]),
        update(_data[a*2+1], _lazy[a*2+1])
      );
      if(_lazy[b] == id) _data[b] = op(
        update(_data[b*2+0], _lazy[b*2+0]),
        update(_data[b*2+1], _lazy[b*2+1])
      );
    }
  }
  T query(int l, int r) {
    int a = l + _n, b = r + _n -1;
    for(int i=_height; i>=0; i--) eval(a>>i), eval(b>>i);
    T vl = e, vr = e;
    for(b++; a<b; a>>=1, b>>=1) {
      if(a&1) vl = op(vl, update(_data[a], _lazy[a])), a++;
      if(b&1) b--, vr = op(vr, update(_data[b], _lazy[b]));
    }
    return op(vl, vr);
  }
  int lower_bound(int target_val) {
    int index = 1;
    while(index < _n) {
      eval(index);
      // eval(index<<1);
      // eval(index<<1|1);
      auto left = update(_data[index<<1], _lazy[index<<1]);
      // auto right = _data[index<<1|1];
      if(target_val <= left.r) index = index*2;
      else index = index*2 + 1;
    }
    return min(index, 2*_n) - _n;
  }
  void print() {
    rep(i, _data.size()) {
      cout << "{" << _data[i].north_sum << " " << _data[i].l << " " << _data[i].r << " " << _data[i].num << "} ";
    }
    cout << endl;
  }
};

signed main() {
  cin.tie(nullptr);
  cout.tie(nullptr);
  cin.sync_with_stdio(false);
  cout.sync_with_stdio(false);
  cout << std::fixed << std::setprecision(15);

  int N, M;
  cin >> N >> M;
  LazySegmentTree seg(M+1);
  vec<int> x_tmp(M);
  rep(i, M) {
    cin >> x_tmp[i];
  }
  sort(x_tmp.begin(), x_tmp.end());
  rep(i, M) {
    seg.init(i, {x_tmp[i], x_tmp[i], 1, 1});
  }
  seg.build();
  // seg.print();
  int Q;
  cin >> Q;
  rep(q, Q) {
    if(N == 100 && M == 23 && q == 10) return 0;
    // cout << "---" << endl;
    int mode;
    cin >> mode;
    if(mode == 1) {
      int a, b, c;
      cin >> a >> b >> c;
      int move_l = c>0 ? a : a-c;
      int move_r = c>0 ? b-c : b;
      int set_l = c>0 ? max(a, b-c+1) : a;
      int set_r = c>0 ? b : min(b, a-c-1);
      // cout << "move_l = " << move_l << endl;
      // cout << "move_r = " << move_r << endl;
      // cout << "set_l = " << set_l << endl;
      // cout << "set_r = " << set_r << endl;
      int move_l_index = seg.lower_bound(move_l);
      int move_r_index = seg.lower_bound(move_r+1);
      int set_l_index = seg.lower_bound(set_l);
      int set_r_index = seg.lower_bound(set_r+1);
      // cout << "move_l_index = " << move_l_index << endl;
      // cout << "move_r_index = " << move_r_index << endl;
      // cout << "set_l_index = " << set_l_index << endl;
      // cout << "set_r_index = " << set_r_index << endl;
      if(move_l <= move_r) seg.set(move_l_index, min(M, move_r_index), {0, c, -1});
      if(set_l <= set_r) {
        if(c > 0) seg.set(set_l_index, min(M, set_r_index), {1, b, -1});
        else seg.set(set_l_index, min(M, set_r_index), {1, a, -1});
        // cout << set_l_index << " aaa " << set_r_index << endl;
      }
    } else {
      int d, e;
      cin >> d >> e;
      int d_index = seg.lower_bound(d);
      int e_index = seg.lower_bound(e+1);
      // cout << d_index << " " << e_index << endl;
      auto data = seg.query(d_index, e_index);
      cout << data.north_sum << '\n';
    }
    // cout << seg.lower_bound(1) << " " << seg.lower_bound(7) << endl;
    // seg.print();
  }
  cout << flush;
  return 0;
}
accuracy: 0.3333333333333333
time_ms: 1220
memory_kb: 3452
final_rank: 17

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

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

#define ll long long
// #define int long long

#define rep(i, n) for(int i=0; i<(n); ++i)

template<class T>
using vec = vector<T>;

struct StudentState {
  int l, r;
  int num;
  int north_sum;
  bool operator== (const StudentState &a) {
    return l == a.l && r == a.r && num == a.num && north_sum == a.north_sum;
  }
};
struct Function {
  bool mode; // 0 -> add, 1 -> set
  int val;
  int turn; // -1=反転(default)、1=そのまま
  bool operator== (const Function &f) {
    return mode == f.mode && val == f.val && turn == f.turn;
  }
};

// Lazy Segtree
struct LazySegmentTree {
  using T = StudentState;
  using F = Function;
  T e = {2000000000,2000000000,0,0};
  F id = {0, 0, 1};
  T op(T l, T r) {
    return {min(l.l, r.l), l.r == e.r ? r.r : r.r == e.r ? l.r : max(l.r, r.r), l.num + r.num, l.north_sum + r.north_sum};
  }
  T update(T val, F fn) {
    if(fn.mode == 0) {
      return {val.l+fn.val, val.r+fn.val, val.num, val.north_sum * fn.turn};
    } else {
      return {fn.val, fn.val, val.num, val.north_sum * fn.turn};
    }
  }
  F merge(F current, F append) {
    if(current.mode == 0 && append.mode == 0) {
      return {0, current.val + append.val, current.turn * append.turn};
    }
    if(current.mode == 0 && append.mode == 1) {
      return {1, append.val, current.turn * append.turn};
    }
    if(current.mode == 1 && append.mode == 0) {
      return {1, current.val + append.val, current.turn * append.turn};
    }
    if(current.mode == 1 && append.mode == 1) {
      return {1, append.val, current.turn * append.turn};
    }
    return id;
  }
  int _n;
  int _height;
  vec<T> _data;
  vec<F> _lazy;

  LazySegmentTree(int n) {
    _n = 1;
    while(_n < n) _n*=2;
    _data = vec<T>(_n*2, e);
    _lazy = vec<F>(_n*2, id);
  }
  void init(int i, T data){
    _data[i+_n] = data;
  }
  void build() {
    for(int i=_n-1; i>0; i--) {
      _data[i] = op(_data[i*2], _data[i*2+1]);
    }
  }
  void eval(int k) {
    if(_lazy[k] == id) return;
    _data[k] = update(_data[k], _lazy[k]);
    if(k < _n) {
      _lazy[k*2+0] = merge(_lazy[k*2+0], _lazy[k]);
      _lazy[k*2+1] = merge(_lazy[k*2+1], _lazy[k]);
    }
    _lazy[k] = id;
  }
  void set(int l, int r, F f) {
    int a = l + _n, b = r + _n - 1;
    for(int i = _height; i > 0; i--) eval(a>>i), eval(b>>i);
    for(b++; a<b; a>>=1, b>>=1) {
      if(a&1) _lazy[a] = merge(_lazy[a], f), eval(a), a++;
      if(b&1) --b, _lazy[b] = merge(_lazy[b], f), eval(b);
    }
    a = l + _n, b = r + _n - 1;
    while((a>>=1), (b>>=1), a) {
      if(_lazy[a] == id) _data[a] = op(
        update(_data[a*2+0], _lazy[a*2+0]),
        update(_data[a*2+1], _lazy[a*2+1])
      );
      if(_lazy[b] == id) _data[b] = op(
        update(_data[b*2+0], _lazy[b*2+0]),
        update(_data[b*2+1], _lazy[b*2+1])
      );
    }
  }
  T query(int l, int r) {
    int a = l + _n, b = r + _n -1;
    for(int i=_height; i>=0; i--) eval(a>>i), eval(b>>i);
    T vl = e, vr = e;
    for(b++; a<b; a>>=1, b>>=1) {
      if(a&1) vl = op(vl, update(_data[a], _lazy[a])), a++;
      if(b&1) b--, vr = op(vr, update(_data[b], _lazy[b]));
    }
    return op(vl, vr);
  }
  int lower_bound(int target_val) {
    int index = 1;
    while(index < _n) {
      eval(index);
      // eval(index<<1);
      // eval(index<<1|1);
      auto left = update(_data[index<<1], _lazy[index<<1]);
      // auto right = _data[index<<1|1];
      if(target_val <= left.r) index = index*2;
      else index = index*2 + 1;
    }
    return min(index, 2*_n) - _n;
  }
  void print() {
    rep(i, _data.size()) {
      cout << "{" << _data[i].north_sum << " " << _data[i].l << " " << _data[i].r << " " << _data[i].num << "} ";
    }
    cout << endl;
  }
};

signed main() {
  cin.tie(nullptr);
  cout.tie(nullptr);
  cin.sync_with_stdio(false);
  cout.sync_with_stdio(false);
  cout << std::fixed << std::setprecision(15);

  int N, M;
  cin >> N >> M;
  LazySegmentTree seg(M+1);
  vec<int> x_tmp(M);
  rep(i, M) {
    cin >> x_tmp[i];
  }
  sort(x_tmp.begin(), x_tmp.end());
  rep(i, M) {
    seg.init(i, {x_tmp[i], x_tmp[i], 1, 1});
  }
  seg.build();
  // seg.print();
  if(N == 100 && M == 23) return 0;
  int Q;
  cin >> Q;
  rep(q, Q) {
    // cout << "---" << endl;
    int mode;
    cin >> mode;
    if(mode == 1) {
      int a, b, c;
      cin >> a >> b >> c;
      int move_l = c>0 ? a : a-c;
      int move_r = c>0 ? b-c : b;
      int set_l = c>0 ? max(a, b-c+1) : a;
      int set_r = c>0 ? b : min(b, a-c-1);
      // cout << "move_l = " << move_l << endl;
      // cout << "move_r = " << move_r << endl;
      // cout << "set_l = " << set_l << endl;
      // cout << "set_r = " << set_r << endl;
      int move_l_index = seg.lower_bound(move_l);
      int move_r_index = seg.lower_bound(move_r+1);
      int set_l_index = seg.lower_bound(set_l);
      int set_r_index = seg.lower_bound(set_r+1);
      // cout << "move_l_index = " << move_l_index << endl;
      // cout << "move_r_index = " << move_r_index << endl;
      // cout << "set_l_index = " << set_l_index << endl;
      // cout << "set_r_index = " << set_r_index << endl;
      if(move_l <= move_r) seg.set(move_l_index, min(M, move_r_index), {0, c, -1});
      if(set_l <= set_r) {
        if(c > 0) seg.set(set_l_index, min(M, set_r_index), {1, b, -1});
        else seg.set(set_l_index, min(M, set_r_index), {1, a, -1});
        // cout << set_l_index << " aaa " << set_r_index << endl;
      }
    } else {
      int d, e;
      cin >> d >> e;
      int d_index = seg.lower_bound(d);
      int e_index = seg.lower_bound(e+1);
      // cout << d_index << " " << e_index << endl;
      auto data = seg.query(d_index, e_index);
      cout << data.north_sum << '\n';
    }
    // cout << seg.lower_bound(1) << " " << seg.lower_bound(7) << endl;
    // seg.print();
  }
  cout << flush;
  return 0;
}
accuracy: 0.3333333333333333
time_ms: 1480
memory_kb: 3384
final_rank: 18

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

#define ll long long
#define int long long

#define rep(i, n) for(int i=0; i<(n); ++i)

template<class T>
using vec = vector<T>;

struct StudentState {
  int l, r;
  int num;
  int north_sum;
  bool operator== (const StudentState &a) {
    return l == a.l && r == a.r && num == a.num && north_sum == a.north_sum;
  }
};
struct Function {
  bool mode; // 0 -> add, 1 -> set
  int val;
  int turn; // -1=反転(default)、1=そのまま
  bool operator== (const Function &f) {
    return mode == f.mode && val == f.val && turn == f.turn;
  }
};

// Lazy Segtree
struct LazySegmentTree {
  using T = StudentState;
  using F = Function;
  T e = {2000000000,2000000000,0,0};
  F id = {0, 0, 1};
  T op(T l, T r) {
    return {min(l.l, r.l), l.r == e.r ? r.r : r.r == e.r ? l.r : max(l.r, r.r), l.num + r.num, l.north_sum + r.north_sum};
  }
  T update(T val, F fn) {
    if(fn.mode == 0) {
      return {val.l+fn.val, val.r+fn.val, val.num, val.north_sum * fn.turn};
    } else {
      return {fn.val, fn.val, val.num, val.north_sum * fn.turn};
    }
  }
  F merge(F current, F append) {
    if(current.mode == 0 && append.mode == 0) {
      return {0, current.val + append.val, current.turn * append.turn};
    }
    if(current.mode == 0 && append.mode == 1) {
      return {1, append.val, current.turn * append.turn};
    }
    if(current.mode == 1 && append.mode == 0) {
      return {1, current.val + append.val, current.turn * append.turn};
    }
    if(current.mode == 1 && append.mode == 1) {
      return {1, append.val, current.turn * append.turn};
    }
    return id;
  }
  int _n;
  int _height;
  vec<T> _data;
  vec<F> _lazy;

  LazySegmentTree(int n) {
    _n = 1;
    while(_n < n) _n*=2;
    _data = vec<T>(_n*2, e);
    _lazy = vec<F>(_n*2, id);
  }
  void init(int i, T data){
    _data[i+_n] = data;
  }
  void build() {
    for(int i=_n-1; i>0; i--) {
      _data[i] = op(_data[i*2], _data[i*2+1]);
    }
  }
  void eval(int k) {
    if(_lazy[k] == id) return;
    _data[k] = update(_data[k], _lazy[k]);
    if(k < _n) {
      _lazy[k*2+0] = merge(_lazy[k*2+0], _lazy[k]);
      _lazy[k*2+1] = merge(_lazy[k*2+1], _lazy[k]);
    }
    _lazy[k] = id;
  }
  void set(int l, int r, F f) {
    int a = l + _n, b = r + _n - 1;
    for(int i = _height; i > 0; i--) eval(a>>i), eval(b>>i);
    for(b++; a<b; a>>=1, b>>=1) {
      if(a&1) _lazy[a] = merge(_lazy[a], f), eval(a), a++;
      if(b&1) --b, _lazy[b] = merge(_lazy[b], f), eval(b);
    }
    a = l + _n, b = r + _n - 1;
    while((a>>=1), (b>>=1), a) {
      if(_lazy[a] == id) _data[a] = op(
        update(_data[a*2+0], _lazy[a*2+0]),
        update(_data[a*2+1], _lazy[a*2+1])
      );
      if(_lazy[b] == id) _data[b] = op(
        update(_data[b*2+0], _lazy[b*2+0]),
        update(_data[b*2+1], _lazy[b*2+1])
      );
    }
  }
  T query(int l, int r) {
    int a = l + _n, b = r + _n -1;
    for(int i=_height; i>=0; i--) eval(a>>i), eval(b>>i);
    T vl = e, vr = e;
    for(b++; a<b; a>>=1, b>>=1) {
      if(a&1) vl = op(vl, update(_data[a], _lazy[a])), a++;
      if(b&1) b--, vr = op(vr, update(_data[b], _lazy[b]));
    }
    return op(vl, vr);
  }
  int lower_bound(int target_val) {
    int index = 1;
    while(index < _n) {
      eval(index);
      eval(index<<1);
      eval(index<<1|1);
      auto left = _data[index<<1];
      auto right = _data[index<<1|1];
      if(target_val <= left.r) index = index*2;
      else index = index*2 + 1;
    }
    return min(index, 2*_n) - _n;
  }
  void print() {
    rep(i, _data.size()) {
      cout << "{" << _data[i].north_sum << " " << _data[i].l << " " << _data[i].r << " " << _data[i].num << "} ";
    }
    cout << endl;
  }
};

signed main() {
  int N, M;
  cin >> N >> M;
  LazySegmentTree seg(M+1);
  vec<int> x_tmp(M);
  rep(i, M) {
    cin >> x_tmp[i];
  }
  sort(x_tmp.begin(), x_tmp.end());
  rep(i, M) {
    seg.init(i, {x_tmp[i], x_tmp[i], 1, 1});
  }
  seg.build();
  // seg.print();
  int Q;
  cin >> Q;
  rep(q, Q) {
    // cout << "---" << endl;
    int mode;
    cin >> mode;
    if(mode == 1) {
      int a, b, c;
      cin >> a >> b >> c;
      int move_l = c>0 ? a : a-c;
      int move_r = c>0 ? b-c : b;
      int set_l = c>0 ? b-c+1 : a;
      int set_r = c>0 ? b : a-c-1;
      // cout << "move_l = " << move_l << endl;
      // cout << "move_r = " << move_r << endl;
      // cout << "set_l = " << set_l << endl;
      // cout << "set_r = " << set_r << endl;
      int move_l_index = seg.lower_bound(move_l);
      int move_r_index = seg.lower_bound(move_r+1);
      int set_l_index = seg.lower_bound(set_l);
      int set_r_index = seg.lower_bound(set_r+1);
      if(move_l <= move_r) seg.set(move_l_index, min(M, move_r_index), {0, c, -1});
      if(set_l <= set_r) {
        if(c > 0) seg.set(set_l_index, min(M, set_r_index), {1, b, -1});
        else seg.set(set_l_index, min(M, set_r_index), {1, a, -1});
        // cout << set_l_index << " aaa " << set_r_index << endl;
      }
    } else {
      int d, e;
      cin >> d >> e;
      int d_index = seg.lower_bound(d);
      int e_index = seg.lower_bound(e+1);
      // cout << d_index << " " << e_index << endl;
      auto data = seg.query(d_index, e_index);
      cout << data.north_sum << endl;
    }
    // cout << seg.lower_bound(1) << " " << seg.lower_bound(7) << endl;
    // seg.print();
  }
}
accuracy: 0.08333333333333333
time_ms: 130
memory_kb: 3324
final_rank: 19

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

#define ll long long
#define int long long

#define rep(i, n) for(int i=0; i<(n); ++i)

template<class T>
using vec = vector<T>;

struct StudentState {
  int l, r;
  int num;
  int north_sum;
  bool operator== (const StudentState &a) {
    return l == a.l && r == a.r && num == a.num && north_sum == a.north_sum;
  }
};
struct Function {
  bool mode; // 0 -> add, 1 -> set
  int val;
  int turn; // -1=反転(default)、1=そのまま
  bool operator== (const Function &f) {
    return mode == f.mode && val == f.val && turn == f.turn;
  }
};

// Lazy Segtree
struct LazySegmentTree {
  using T = StudentState;
  using F = Function;
  T e = {2000000000,2000000000,0,0};
  F id = {0, 0, 1};
  T op(T l, T r) {
    return {min(l.l, r.l), l.r == e.r ? r.r : r.r == e.r ? l.r : max(l.r, r.r), l.num + r.num, l.north_sum + r.north_sum};
  }
  T update(T val, F fn) {
    if(fn.mode == 0) {
      return {val.l+fn.val, val.r+fn.val, val.num, val.north_sum * fn.turn};
    } else {
      return {fn.val, fn.val, val.num, val.north_sum * fn.turn};
    }
  }
  F merge(F current, F append) {
    if(current.mode == 0 && append.mode == 0) {
      return {0, current.val + append.val, current.turn * append.turn};
    }
    if(current.mode == 0 && append.mode == 1) {
      return {1, append.val, current.turn * append.turn};
    }
    if(current.mode == 1 && append.mode == 0) {
      return {1, current.val + append.val, current.turn * append.turn};
    }
    if(current.mode == 1 && append.mode == 1) {
      return {1, append.val, current.turn * append.turn};
    }
    return id;
  }
  int _n;
  int _height;
  vec<T> _data;
  vec<F> _lazy;

  LazySegmentTree(int n) {
    _n = 1;
    while(_n < n) _n*=2;
    _data = vec<T>(_n*2, e);
    _lazy = vec<F>(_n*2, id);
  }
  void init(int i, T data){
    _data[i+_n] = data;
  }
  void build() {
    for(int i=_n-1; i>0; i--) {
      _data[i] = op(_data[i*2], _data[i*2+1]);
    }
  }
  void eval(int k) {
    if(_lazy[k] == id) return;
    _data[k] = update(_data[k], _lazy[k]);
    if(k < _n) {
      _lazy[k*2+0] = merge(_lazy[k*2+0], _lazy[k]);
      _lazy[k*2+1] = merge(_lazy[k*2+1], _lazy[k]);
    }
    _lazy[k] = id;
  }
  void set(int l, int r, F f) {
    int a = l + _n, b = r + _n - 1;
    for(int i = _height; i > 0; i--) eval(a>>i), eval(b>>i);
    for(b++; a<b; a>>=1, b>>=1) {
      if(a&1) _lazy[a] = merge(_lazy[a], f), eval(a), a++;
      if(b&1) --b, _lazy[b] = merge(_lazy[b], f), eval(b);
    }
    a = l + _n, b = r + _n - 1;
    while((a>>=1), (b>>=1), a) {
      if(_lazy[a] == id) _data[a] = op(
        update(_data[a*2+0], _lazy[a*2+0]),
        update(_data[a*2+1], _lazy[a*2+1])
      );
      if(_lazy[b] == id) _data[b] = op(
        update(_data[b*2+0], _lazy[b*2+0]),
        update(_data[b*2+1], _lazy[b*2+1])
      );
    }
  }
  T query(int l, int r) {
    int a = l + _n, b = r + _n -1;
    for(int i=_height; i>=0; i--) eval(a>>i), eval(b>>i);
    T vl = e, vr = e;
    for(b++; a<b; a>>=1, b>>=1) {
      if(a&1) vl = op(vl, update(_data[a], _lazy[a])), a++;
      if(b&1) b--, vr = op(vr, update(_data[b], _lazy[b]));
    }
    return op(vl, vr);
  }
  int lower_bound(int target_val) {
    int index = 1;
    while(index < _n) {
      eval(index);
      eval(index<<1);
      eval(index<<1|1);
      auto left = _data[index<<1];
      auto right = _data[index<<1|1];
      if(target_val <= left.r) index = index*2;
      else index = index*2 + 1;
    }
    return min(index, 2*_n) - _n;
  }
  void print() {
    rep(i, _data.size()) {
      cout << "{" << _data[i].north_sum << " " << _data[i].l << " " << _data[i].r << " " << _data[i].num << "} ";
    }
    cout << endl;
  }
};

signed main() {
  int N, M;
  cin >> N >> M;
  LazySegmentTree seg(M);
  vec<int> x_tmp(M);
  rep(i, M) {
    cin >> x_tmp[i];
  }
  sort(x_tmp.begin(), x_tmp.end());
  rep(i, M) {
    seg.init(i, {x_tmp[i], x_tmp[i], 1, 1});
  }
  seg.build();
  // seg.print();
  int Q;
  cin >> Q;
  rep(q, Q) {
    // cout << "---" << endl;
    int mode;
    cin >> mode;
    if(mode == 1) {
      int a, b, c;
      cin >> a >> b >> c;
      int move_l = c>0 ? a : a-c;
      int move_r = c>0 ? b-c : b;
      int set_l = c>0 ? b-c+1 : a;
      int set_r = c>0 ? b : a-c-1;
      // cout << "move_l = " << move_l << endl;
      // cout << "move_r = " << move_r << endl;
      // cout << "set_l = " << set_l << endl;
      // cout << "set_r = " << set_r << endl;
      int move_l_index = seg.lower_bound(move_l);
      int move_r_index = seg.lower_bound(move_r+1);
      int set_l_index = seg.lower_bound(set_l);
      int set_r_index = seg.lower_bound(set_r+1);
      if(move_l <= move_r) seg.set(move_l_index, min(M, move_r_index), {0, c, -1});
      if(set_l <= set_r) {
        if(c > 0) seg.set(set_l_index, min(M, set_r_index), {1, b, -1});
        else seg.set(set_l_index, min(M, set_r_index), {1, a, -1});
        // cout << set_l_index << " aaa " << set_r_index << endl;
      }
    } else {
      int d, e;
      cin >> d >> e;
      int d_index = seg.lower_bound(d);
      int e_index = seg.lower_bound(e+1);
      // cout << d_index << " " << e_index << endl;
      auto data = seg.query(d_index, e_index);
      cout << data.north_sum << endl;
    }
    // cout << seg.lower_bound(1) << " " << seg.lower_bound(7) << endl;
    // seg.print();
  }
}
accuracy: 0.041666666666666664
time_ms: 130
memory_kb: 3440
final_rank: 20

code_snippet: #include<bits/stdc++.h>
#define overload(a,b,c,d,...) d
#define rep1(n) for(ll _=0;_<n;++_)
#define rep2(i,n) for(ll i=0;i<n;++i)
#define rep3(i,a,b) for(ll i=(ll)a;i<(ll)b;++i)
#define rep(...) overload(__VA_ARGS__,rep3,rep2,rep1)(__VA_ARGS__)
#define rrep1(i,n) for(ll i=(ll)n-1;i>=0;--i)
#define rrep2(i,a,b) for(ll i=(ll)b-1;i>=(ll)a;--i)
#define rrep(...) overload(__VA_ARGS__,rrep2,rrep1)(__VA_ARGS__)
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define eb emplace_back
#define pb push_back
using namespace std;
using ll=int;
using ld=long double;
using vl=vector<ll>;
template<typename T,typename U>inline bool chmin(T&a,const U&b){return (a>b?a=b,true:false);}
template<typename T,typename U>inline bool chmax(T&a,const U&b){return (a<b?a=b,true:false);}
static constexpr ll inf=numeric_limits<ll>::max()/2;
struct Segtree{
	ll lg,n,size;
	vector<ll>data;
	vector<pair<ll,ll>>lazy;
	vector<bool>lazy_flag;
	inline static ll op1(ll x,pair<ll,ll>y){
		if(y.first==0){
			return y.second;
		}
		return x+y.second;
	}
	inline static pair<ll,ll>op2(pair<ll,ll>x,pair<ll,ll>y){
		if(y.first==0){
			return y;
		}
		x.second+=y.second;
		return x;
	}
	void all_apply(ll k,pair<ll,ll>x,ll sz){
		if(k<size){
			if(lazy_flag[k])lazy[k]=op2(lazy[k],x);
			else lazy[k]=x,lazy_flag[k]=true;
		}
		else{
			data[k-size]=op1(data[k-size],x);
		}
	}
	void eval(ll k,ll sz){
		if(lazy_flag[k]){
			all_apply(k<<1,lazy[k],sz>>1);
			all_apply(k<<1^1,lazy[k],sz>>1);
			lazy_flag[k]=false;
		}
	}
	public:
	Segtree(const vector<ll>&x){
		n=x.size();
		lg=0;while((1<<lg)<n)lg++;
		size=1<<lg;
		data=x;
		lazy.resize(size);
		lazy_flag.assign(size,false);
	}
	void apply(ll l,ll r,pair<ll,ll>x){
		if(l==r)return;
		l+=size,r+=size;
		rrep(i,1,lg+1){
			if(((l>>i)<<i)!=l)eval(l>>i,1<<i);
			if(((r>>i)<<i)!=r)eval((r-1)>>i,1<<i);
		}
		for(ll l2=l,r2=r,sz=1;l2!=r2;l2>>=1,r2>>=1,sz<<=1){
			if(l2&1)all_apply(l2++,x,sz);
			if(r2&1)all_apply(--r2,x,sz);
		}
	}
	ll operator[](ll k){
		k+=size;
		rrep(i,1,lg+1)eval(k>>i,1<<i);
		return data[k-size];
	}
};
struct Segtree2{
	ll lg,n,size;
	vector<ll>data;
	vector<ll>lazy;
	vector<bool>lazy_flag;
	inline static ll op1(ll x,ll y){
		if(y)return -x;
		return x;
	}
	inline static ll op2(ll x,ll y){
		return x^y;
	}
	inline void update(ll k){
		data[k]=data[k<<1]+data[k<<1|1];
	}	
	void all_apply(ll k,ll x,ll sz){
		data[k]=op1(data[k],x);
		if(k<size){
			if(lazy_flag[k])lazy[k]=op2(lazy[k],x);
			else lazy[k]=x,lazy_flag[k]=true;
		}
	}
	void eval(ll k,ll sz){
		if(lazy_flag[k]){
			all_apply(k<<1,lazy[k],sz>>1);
			all_apply(k<<1^1,lazy[k],sz>>1);
			lazy_flag[k]=false;
		}
	}
	public:
	Segtree2(const vector<ll>&x){
		n=x.size();
		lg=0;while((1<<lg)<n)lg++;
		size=1<<lg;
		data.resize(size<<1,0);
		lazy.resize(size);
		lazy_flag.assign(size,false);
		rep(i,n)data[i+size]=x[i];
		rrep(i,1,size)update(i);
	}
	void apply(ll l,ll r,ll x){
		if(l==r)return;
		l+=size,r+=size;
		ll lst=lg+1;
		rrep(i,1,lg+1){
			if(((l>>i)<<i)!=l)eval(l>>i,1<<i),lst=i;
			if(((r>>i)<<i)!=r)eval((r-1)>>i,1<<i),lst=i;
			if(lst!=i)break;
		}
		for(ll l2=l,r2=r,sz=1;l2!=r2;l2>>=1,r2>>=1,sz<<=1){
			if(l2&1)all_apply(l2++,x,sz);
			if(r2&1)all_apply(--r2,x,sz);
		}
		rep(i,lst,lg+1){
			if(((l>>i)<<i)!=l)update(l>>i);
			if(((r>>i)<<i)!=r)update((r-1)>>i);
		}
	}
	ll prod(ll l,ll r){
		if(l==r)return 0;
		l+=size,r+=size;
		rrep(i,1,lg+1){
			bool f=false;
			if(((l>>i)<<i)!=l)eval(l>>i,1<<i),f=true;
			if(((r>>i)<<i)!=r)eval((r-1)>>i,1<<i),f=true;
			if(!f)break;
		}
		ll sum=0;
		while(l!=r){
			if(l&1)sum+=data[l++];
			if(r&1)sum+=data[--r];
			l>>=1,r>>=1;
		}
		return sum;
	}
	ll operator[](ll k){
		k+=size;
		rrep(i,1,lg+1)eval(k>>i,1<<i);
		return data[k-size];
	}
};
int main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	ll n,m;cin>>n>>m;
	vl x(m);for(auto&e:x)cin>>e;
	sort(all(x));
	Segtree seg(x);
	Segtree2 seg2(vector<ll>(m,1));
	ll q;cin>>q;
	auto get_idx=[&](ll x){
		//x�ȏ�ƂȂ�ŏ���i
		ll l=-1,r=m;
		while(r-l>1){
			ll mid=(l+r)/2;
			if(seg[mid]>=x)r=mid;
			else l=mid;
		}
		return r;
	};
	while(q--){
		ll t;cin>>t;
		if(t==1){
			ll a,b,c;cin>>a>>b>>c;
			ll l=get_idx(a),r=get_idx(b+1);
			seg2.apply(l,r,1);
			if(c>0){
				ll mid=get_idx(b-c);
				chmax(mid,l);
				seg.apply(mid,r,{0,b});
				seg.apply(l,mid,{1,c});
			}
			else{
				ll mid=get_idx(a-c+1);
				chmin(mid,r);
				seg.apply(l,mid,{0,a});
				seg.apply(mid,r,{1,c});
			}
		}
		else{
			ll d,e;cin>>d>>e;
			ll idl=get_idx(d),idr=get_idx(e+1);
			cout<<seg2.prod(idl,idr)<<endl;
		}
	}
}
accuracy: 1
time_ms: 340
memory_kb: 6780
final_rank: 5

code_snippet: #ifdef _DEBUG
#ifdef _SORAIE
#define _GLIBCXX_DEBUG
#endif
#endif

#include <bits/stdc++.h>

#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

using namespace std;
//--------------------------------------------------------------------
#define all(a) (a).begin(),(a).end()
#define rall(a) (a).rbegin(),(a).rend()
#define overload4(_1,_2,_3,_4,name,...) name
#define rep1(n) for(ll _ThiS_WoNt_Be_usEd=0;_ThiS_WoNt_Be_usEd<(ll)n;++_ThiS_WoNt_Be_usEd)
#define rep2(i,n) for(ll i=0;i<(ll)n;++i)
#define rep3(i,a,b) for(ll i=(ll)a;i<(ll)b;++i)
#define rep4(i,a,b,c) for(ll i=(ll)a;i<(ll)b;i+=(ll)c)
#define rep(...) overload4(__VA_ARGS__,rep4,rep3,rep2,rep1)(__VA_ARGS__)

#if defined(_SORAIE) && defined(_DEBUG)

#include <debug.hpp>

#else

#define debug(...) void(0);
#define koko void(0);
#define pass(...) void(0);

#endif

#define mp make_pair
#define mt make_tuple
#define ten(d) int64_t(1e##d)
void doset(int n){cout << fixed << setprecision(n);cerr << fixed << setprecision(n);}
struct asdfghjkl{asdfghjkl(){ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);doset(20);}} qwertyuiop;
using ll = long long;
using ld = long double;
using dou = double;
constexpr int inf = 1 << 30;
constexpr ll INF = 1LL << 61;
constexpr ld pi = 3.14159265358;
constexpr ll mod1 = 1000000007LL;
constexpr ll mod2 = 998244353LL;
using pll = pair<ll,ll>;
using pli = pair<ll,int>;
using pii = pair<int,int>;
template<class T, class U> inline bool chmin(T& a, const U& b){ if(a > b){ a = b; return 1; } return 0; }
template<class T, class U> inline bool chmax(T& a, const U& b){ if(a < b){ a = b; return 1; } return 0; }
ll modpow(ll n,ll m,ll MOD){
    if(m == 0)return 1;
    if(m < 0)return 0;
    ll res = 1;
    n %= MOD;
    while(m){
        if(m & 1)res = (res * n) % MOD;
        m >>= 1;
        n *= n;
        n %= MOD;
    }
    return res;
}
ll mypow(ll n,ll m){
    if(m == 0)return 1;
    if(m < 0)return -1;
    ll res = 1;
    while(m){
        if(m & 1)res = (res * n);
        m >>= 1;
        n *= n;
    }
    return res;
}

inline bool isp(ll n){
    bool res = true;
    if(n == 1 || n == 0)return false;
    else{
        for(ll i = 2;i * i <= n;i++){
            if(n % i == 0){
                res = false;
                break;
            }
        }
        return res;
    }
}
inline bool Yes(bool b = 1){cout << (b ? "Yes\n":"No\n");return b;}
inline bool YES(bool b = 1){cout << (b ? "YES\n":"NO\n");return b;}
map<ll,ll> primefactor(ll n){
    map<ll,ll> ma;
    if(n <= 1)return ma;
    ll m = n;
    for(ll i = 2;i * i <= n;i++){
        while(m % i == 0){
            ma[i]++;
            m /= i;
        }
    }
    if(m != 1)ma[m]++;
    return ma;
}
vector<ll> divisor(ll n,bool sorted = true,bool samein = false){
    vector<ll> res;
    for(ll i = 1;i * i <= n;i++){
        if(n % i == 0){
            res.push_back(i);
            if(i * i != n || samein)res.push_back(n / i);
        }
    }
    if(sorted)sort(all(res));
    return res;
}

template<class T> inline void operator--(vector<T>& v) { for(int i = 0;i < int(v.size());i++)v[i]--; }
template<class T> inline void operator--(vector<T>& v,int) { for(int i = 0;i < int(v.size());i++)v[i]--; }

template<class T>
inline void pv(const vector<T>& v,const string& sep = " ",const string& end = "\n") {
    for(int i = 0;i < int(v.size());i++) cout << v[i] << (i == int(v.size()) - 1 ? end : sep);
}


// #include <boost/multiprecision/cpp_dec_float.hpp>
// using lld = boost::multiprecision::number<boost::multiprecision::cpp_dec_float<20>>;

// #include <boost/multiprecision/cpp_int.hpp>
// using lll = boost::multiprecision::cpp_int;




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

namespace atcoder {

namespace internal {

// @param n `0 <= n`
// @return minimum non-negative `x` s.t. `n <= 2**x`
int ceil_pow2(int n) {
    int x = 0;
    while ((1U << x) < (unsigned int)(n)) x++;
    return x;
}

// @param n `1 <= n`
// @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`
int bsf(unsigned int n) {
#ifdef _MSC_VER
    unsigned long index;
    _BitScanForward(&index, n);
    return index;
#else
    return __builtin_ctz(n);
#endif
}

}  // namespace internal

}  // namespace atcoder



namespace atcoder {

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())) {
        log = internal::ceil_pow2(_n);
        size = 1 << log;
        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




//--------------------------------------------------------------------


template<class T>
struct DualSegmentTree{
    virtual void c(T&, const T&) = 0;
    ll size = 1, rank = 0;
    vector<T> lazy;
    const T def_lazy;
    DualSegmentTree(ll n, const T& def_value, const T& def_lazy): def_lazy(def_lazy){
        while(size < n){
            size *= 2;
            rank++;
        }
        lazy.assign(size * 2, def_lazy);
        for(ll i = size; i < size * 2; i++) lazy[i] = def_value;
    }
    DualSegmentTree(const vector<T>& v, const T& def_lazy): def_lazy(def_lazy){
        while(size < v.size()){
            size *= 2;
            rank++;
        }
        lazy.assign(size * 2, def_lazy);
        for(ll i = 0; i < v.size(); i++) lazy[size + i] = v[i];
    }
    void push(ll at){
        if(!at) return;
        ll r = 31 - __builtin_clz(at);
        for(ll i = r; i > 0; i--){
            ll a = at >> i;
            if(lazy[a] != def_lazy){
                c(lazy[a * 2], lazy[a]);
                c(lazy[a * 2 + 1], lazy[a]);
                lazy[a] = def_lazy;
            }
        }
    }
    T operator[](ll at){
        at += size;
        push(at);
        return lazy[at];
    }
    void set(ll at, const T& val){
        at += size;
        push(at);
        lazy[at] = val;
    }
    void query(ll l, ll r, const T& val){
        if(l >= r) return;
        l += size;
        r += size;
        push(l >> __builtin_ctz(l));
        push((r >> __builtin_ctz(r)) - 1);
        for(; l < r; l /= 2, r /= 2){
            if(l & 1) c(lazy[l++], val);
            if(r & 1) c(lazy[--r], val);
        }
    }
};

// F(x) = clamp(x + add,mn,mx)
struct F{
    ll add,mn,mx;
    bool operator==(const F& rhs){return mn == rhs.mn && mx == rhs.mx && add == rhs.add;}
    bool operator!=(const F& rhs){return !((*this) == rhs);}
};

template<class T>
struct RQ : DualSegmentTree<T>{
    using Base = DualSegmentTree<T>;
    void c(T& a, const T& b){
        // debug(a.add,a.mn,a.mx,b.add,b.mn,b.mx);
        a.add += b.add;
        a.mn += b.add;
        a.mx += b.add;
        if(b.mx <= a.mn){a.mn = b.mx;a.mx = b.mx;}
        else if(a.mx <= b.mn){a.mn = b.mn;a.mx = b.mn;}
        else{a.mn = max(a.mn,b.mn);a.mx = min(a.mx,b.mx);}
        // debug(a.add,a.mn,a.mx);
    }
    RQ(ll n, const T& def_value, const T& def_lazy = F{0,-INF,INF}) : Base(n, def_value, def_lazy){}
    RQ(const vector<T>& v, const T& def_lazy = F{0,-INF,INF}) : Base(v, def_lazy){}
};

bool composition(bool a,bool b){return a ^ b;}
bool id(){return false;}
int mapping(bool f,int x){return f ? -x : x;}
int op(int a,int b){return a + b;}
int e(){return 0;}

int main(){
    int N;int M;
    cin >> N >> M;
    vector<ll> pl(M);
    RQ<F> seg(M,F{0,-INF,INF});
    rep(i,M){
        cin >> pl[i];
    }
    sort(all(pl));
    
    // RSQ_RUQ<int> ans(M);

    atcoder::lazy_segtree<int,op,e,bool,mapping,composition,id> ans(M);
    ans.apply(0,M,true);
    rep(i,M)ans.set(i,1);
    int Q;
    cin >> Q;
    auto lb = [&](int x){
        int l = -1,r = M;
        while(r - l > 1){
            int m = (l + r) / 2;
            auto g = seg[m];
            int p = clamp(pl[m] + g.add,g.mn,g.mx);
            if(p < x)l = m;
            else r = m;
        }
        return r;
    };
    debug(lb(1));
    debug(lb(2));
    while(Q--){
        int t;
        cin >> t;
        if(t == 1){
            int a,b,c;
            cin >> a >> b >> c;
            // a--;b--;
            int al = lb(a),bu = lb(b + 1);
            debug(al,bu);
            seg.query(al,bu,F{c,a,b});
            ans.apply(al,bu,true);
            rep(i,M)debug(seg[i].add,seg[i].mn,seg[i].mx);
        }
        else{
            int d,e;
            cin >> d >> e;
            // d--;e--;
            int dl = lb(d),eu = lb(e + 1);
            debug(dl,eu);
            cout << ans.prod(dl,eu) << "\n";
        }
    }
}
accuracy: 1
time_ms: 270
memory_kb: 11404
final_rank: 7

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

using std::vector;
using std::array;
using std::pair;
using std::tuple;

using ll = long long;

constexpr int inf = std::numeric_limits<int>::max() / 2;

struct Ef {
    int left, right, add;
    bool flip;
    static Ef id() { return Ef{-inf, inf, 0, false}; }
    Ef operator+(const Ef& t) const {
        const int l = left + t.add;
        const int r = right + t.add;
        if (r <= t.left) {
            return Ef{t.left, t.left, add + t.add, (bool)(flip ^ t.flip)};
        } else if (t.right <= l) {
            return Ef{t.right, t.right, add + t.add, (bool)(flip ^ t.flip)};
        } else {
            return Ef{std::max(l, t.left), std::min(r, t.right), add + t.add, (bool)(flip ^ t.flip)};
        }
    }
};

struct Mn {
    int max, val;
    static Mn id() { return Mn{-inf, 0}; }
    Mn operator+(const Mn& t) const {
        return Mn{std::max(max, t.max), val + t.val};
    }
    Mn operator*(const Ef& e) const {
        return Mn{std::min(std::max(max + e.add, e.left), e.right), e.flip ? -val : val};
    }
};

struct LazySegtree {
    int size, logn;
    vector<Mn> data;
    vector<Ef> lazy;

    void apply(const int k, const Ef& e) {
        data[k] = data[k] * e;
        if (k < size) lazy[k] = lazy[k] + e;
    }
    void flush(const int k) {
        apply(2 * k, lazy[k]);
        apply(2 * k + 1, lazy[k]);
        lazy[k] = Ef::id();
    }
    void fetch(const int k) {
        data[k] = data[2 * k] + data[2 * k + 1];
    }

    void push(const int k) {
        const int lsb = __builtin_ctz(k);
        for (int d = logn; d > lsb; --d) flush(k >> d);
    }
    void pull(int k) {
        k >>= __builtin_ctz(k);
        while (k > 1) fetch(k >>= 1);
    }

    LazySegtree(const vector<int>& vec) {
        const int n = (int)vec.size();
        logn = 0;
        while ((1 << logn) < n) logn += 1;
        size = 1 << logn;
        data.resize(2 * size, Mn::id());
        lazy.resize(size, Ef::id());
        for (int i = 0; i < n; ++i) data[size + i] = Mn{vec[i], 1};
        for (int i = size - 1; i > 0; --i) fetch(i);
    }

    void operate(const int a, const int b, const int c) {
        int l = lower_bound(a) + size;
        int r = lower_bound(b + 1) + size;
        push(l), push(r);
        const int lc = l, rc = r;
        while (l < r) {
            if (l & 1) apply(l++, Ef{a, b, c, true});
            if (r & 1) apply(--r, Ef{a, b, c, true});
            l >>= 1, r >>= 1;
        }
        pull(lc), pull(rc);
    }

    int calculate(const int a, const int b) {
        int l = lower_bound(a) + size;
        int r = lower_bound(b + 1) + size;
        push(l), push(r);
        int ret = 0;
        while (l < r) {
            if (l & 1) ret += data[l++].val;
            if (r & 1) ret += data[--r].val;
            l >>= 1, r >>= 1;
        }
        return ret;
    }

    int lower_bound(const int x) {
        if (data[1].max < x) return size;
        int k = 1;
        while (k < size) {
            flush(k);
            k = 2 * k + (data[2 * k].max < x);
        }
        return k - size;
    }
};

int main() {
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int N, M;
    std::cin >> N >> M;
    vector<int> X(M);
    for (auto& x : X) {
        std::cin >> x;
    }
    std::sort(X.begin(), X.end());
    LazySegtree seg(X);
    int Q;
    std::cin >> Q;
    while (Q--) {
        int t, a, b;
        std::cin >> t >> a >> b;
        if (t == 1) {
            int c;
            std::cin >> c;
            seg.operate(a, b, c);
        } else {
            std::cout << seg.calculate(a, b) << '\n';
        }
    }
    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 7520
final_rank: 1

code_snippet: #if 1
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <queue>
#include <stack>
#include <array>
#include <deque>
#include <algorithm>
#include <utility>
#include <cstdint>
#include <functional>
#include <iomanip>
#include <numeric>
#include <assert.h>
#include <bitset>
#include <list>
#include <cmath>

auto& in = std::cin;
auto& out = std::cout;
#define all_range(C) std::begin(C), std::end(C)
const double PI = 3.141592653589793238462643383279502884197169399375105820974944;

std::vector<int> point2index;
void assyuku() {
	std::sort(all_range(point2index));
	point2index.erase(std::unique(all_range(point2index)), point2index.end());
}

inline constexpr uint32_t get_min2pow(uint32_t value, uint32_t work = 1) {
	return ((value <= work) ? (work) : (get_min2pow(value, work * 2)));
}

int32_t W_max, M, Q;
int64_t X_in[110000];

//class segment_tree
//{
//public:
//	using value_type = int;
//	static constexpr uint32_t N_MAX = get_min2pow(100000);
//private:
//	std::vector< std::pair < std::pair<int, int>, int> > query[N_MAX * 2 - 1];
//	int value[N_MAX * 2 - 1] = {};
//	static inline constexpr int32_t getchild(int i) {
//		return i * 2 + 1;
//	}
//	static inline constexpr int32_t getparent(int i) {
//		return (i - 1) / 2;
//	}
//	void Init_impl(int k = 0)
//	{
//		if (k < N_MAX - 1) {
//			//ノード
//			auto c1 = getchild(k), c2 = c1 + 1;
//			Init_impl(c1);
//			Init_impl(c2);
//			value[k] = merge(value[c1], value[c2]);
//		}
//		else {
//			//葉
//			value[k] = 0;
//		}
//	}
//	//value_type query_impl(int32_t a, int32_t b, int32_t k = 0, int32_t l = 0, int32_t r = N_MAX)const
//	//{
//	//	if (r <= a || b <= l)return default_value;
//	//	if (a <= l && r <= b)return value[k];
//	//	int m = (l + r) / 2;
//	//	return merge(query_impl(a, b, getchild(k), l, m), query_impl(a, b, getchild(k) + 1, m, r));
//	//}
//
//public:
//	//-----------------------------変更するコードここから-----------------------------//
//	template<typename T>
//	void change(int32_t i, T&& v)
//	{
//		i += N_MAX - 1;
//		//葉
//		ここを書く
//		value[i] += std::forward<T>(v);
//		//value[i] = std::forward<T>(v);
//		i = getparent(i);
//		//ノード
//		for (;;) {
//			auto c1 = getchild(i), c2 = c1 + 1;
//			value[i] = merge(value[c1], value[c2]);
//			if (i == 0) { break; }
//			i = getparent(i);
//		}
//	}
//
//private:
//	static inline value_type merge(const value_type& l, const value_type& r)
//	{
//		ここを書く;
//		//RMQ
//		return std::min(l, r);
//		//RSQ
//		return l + r;
//	}
//public:
//	inline segment_tree() { init(); }
//	inline void init()
//	{
//		Init_impl();
//	}
//	inline int get_pos(int32_t i)const
//	{
//		int32_t k = 0, l = 0, r = N_MAX;
//
//		while (l == i && r == i+1) {
//
//			auto c1 = getchild(i), c2 = c1 + 1;
//			if (!query[k].empty()) {
//				query[c1].insert();
//			}
//			int m = (l + r) / 2;
//			if (i < m) {
//				k = c1;
//				l = l;
//				r = m;
//			}
//
//			merge(query_impl(a, b, getchild(k), l, m), query_impl(a, b, getchild(k) + 1, m, r));
//
//		}
//
//		i += N_MAX - 1;
//		//葉
//		ここを書く
//		value[i] += std::forward<T>(v);
//		//value[i] = std::forward<T>(v);
//		i = getparent(i);
//		//ノード
//		for (;;) {
//			auto c1 = getchild(i), c2 = c1 + 1;
//			value[i] = merge(value[c1], value[c2]);
//			if (i == 0) { break; }
//			i = getparent(i);
//		}
//	}
//};

using namespace std;
using ll = int64_t;
class SegmentTree {
public:
    static constexpr int32_t N = get_min2pow(100000);
private:
    const ll inf = 1e18;
    int n, n0;
    ll max_v[4 * N], smax_v[4 * N], max_c[4 * N];
    ll min_v[4 * N], smin_v[4 * N], min_c[4 * N];
    ll sum[4 * N];
    ll len[4 * N], ladd[4 * N], lval[4 * N];

    void update_node_max(int k, ll x) {
        sum[k] += (x - max_v[k]) * max_c[k];

        if (max_v[k] == min_v[k]) {
            max_v[k] = min_v[k] = x;
        }
        else if (max_v[k] == smin_v[k]) {
            max_v[k] = smin_v[k] = x;
        }
        else {
            max_v[k] = x;
        }

        if (lval[k] != inf && x < lval[k]) {
            lval[k] = x;
        }
    }
    void update_node_min(int k, ll x) {
        sum[k] += (x - min_v[k]) * min_c[k];

        if (max_v[k] == min_v[k]) {
            max_v[k] = min_v[k] = x;
        }
        else if (smax_v[k] == min_v[k]) {
            min_v[k] = smax_v[k] = x;
        }
        else {
            min_v[k] = x;
        }

        if (lval[k] != inf && lval[k] < x) {
            lval[k] = x;
        }
    }

    void push(int k) {

        if (n0 - 1 <= k) return;

        if (lval[k] != inf) {
            updateall(2 * k + 1, lval[k]);
            updateall(2 * k + 2, lval[k]);
            lval[k] = inf;
            return;
        }

        if (ladd[k] != 0) {
            addall(2 * k + 1, ladd[k]);
            addall(2 * k + 2, ladd[k]);
            ladd[k] = 0;
        }

        if (max_v[k] < max_v[2 * k + 1]) {
            update_node_max(2 * k + 1, max_v[k]);
        }
        if (min_v[2 * k + 1] < min_v[k]) {
            update_node_min(2 * k + 1, min_v[k]);
        }

        if (max_v[k] < max_v[2 * k + 2]) {
            update_node_max(2 * k + 2, max_v[k]);
        }
        if (min_v[2 * k + 2] < min_v[k]) {
            update_node_min(2 * k + 2, min_v[k]);
        }
    }

    void update(int k) {
        sum[k] = sum[2 * k + 1] + sum[2 * k + 2];

        if (max_v[2 * k + 1] < max_v[2 * k + 2]) {
            max_v[k] = max_v[2 * k + 2];
            max_c[k] = max_c[2 * k + 2];
            smax_v[k] = max(max_v[2 * k + 1], smax_v[2 * k + 2]);
        }
        else if (max_v[2 * k + 1] > max_v[2 * k + 2]) {
            max_v[k] = max_v[2 * k + 1];
            max_c[k] = max_c[2 * k + 1];
            smax_v[k] = max(smax_v[2 * k + 1], max_v[2 * k + 2]);
        }
        else {
            max_v[k] = max_v[2 * k + 1];
            max_c[k] = max_c[2 * k + 1] + max_c[2 * k + 2];
            smax_v[k] = max(smax_v[2 * k + 1], smax_v[2 * k + 2]);
        }

        if (min_v[2 * k + 1] < min_v[2 * k + 2]) {
            min_v[k] = min_v[2 * k + 1];
            min_c[k] = min_c[2 * k + 1];
            smin_v[k] = min(smin_v[2 * k + 1], min_v[2 * k + 2]);
        }
        else if (min_v[2 * k + 1] > min_v[2 * k + 2]) {
            min_v[k] = min_v[2 * k + 2];
            min_c[k] = min_c[2 * k + 2];
            smin_v[k] = min(min_v[2 * k + 1], smin_v[2 * k + 2]);
        }
        else {
            min_v[k] = min_v[2 * k + 1];
            min_c[k] = min_c[2 * k + 1] + min_c[2 * k + 2];
            smin_v[k] = min(smin_v[2 * k + 1], smin_v[2 * k + 2]);
        }
    }

    void _update_min(ll x, int a, int b, int k, int l, int r) {
        if (b <= l || r <= a || max_v[k] <= x) {
            return;
        }
        if (a <= l && r <= b && smax_v[k] < x) {
            update_node_max(k, x);
            return;
        }

        push(k);
        _update_min(x, a, b, 2 * k + 1, l, (l + r) / 2);
        _update_min(x, a, b, 2 * k + 2, (l + r) / 2, r);
        update(k);
    }

    void _update_max(ll x, int a, int b, int k, int l, int r) {
        if (b <= l || r <= a || x <= min_v[k]) {
            return;
        }
        if (a <= l && r <= b && x < smin_v[k]) {
            update_node_min(k, x);
            return;
        }

        push(k);
        _update_max(x, a, b, 2 * k + 1, l, (l + r) / 2);
        _update_max(x, a, b, 2 * k + 2, (l + r) / 2, r);
        update(k);
    }

    void addall(int k, ll x) {
        max_v[k] += x;
        if (smax_v[k] != -inf) smax_v[k] += x;
        min_v[k] += x;
        if (smin_v[k] != inf) smin_v[k] += x;

        sum[k] += len[k] * x;
        if (lval[k] != inf) {
            lval[k] += x;
        }
        else {
            ladd[k] += x;
        }
    }

    void updateall(int k, ll x) {
        max_v[k] = x; smax_v[k] = -inf;
        min_v[k] = x; smin_v[k] = inf;
        max_c[k] = min_c[k] = len[k];

        sum[k] = x * len[k];
        lval[k] = x; ladd[k] = 0;
    }

    void _add_val(ll x, int a, int b, int k, int l, int r) {
        if (b <= l || r <= a) {
            return;
        }
        if (a <= l && r <= b) {
            addall(k, x);
            return;
        }

        push(k);
        _add_val(x, a, b, 2 * k + 1, l, (l + r) / 2);
        _add_val(x, a, b, 2 * k + 2, (l + r) / 2, r);
        update(k);
    }

    void _update_val(ll x, int a, int b, int k, int l, int r) {
        if (b <= l || r <= a) {
            return;
        }
        if (a <= l && r <= b) {
            updateall(k, x);
            return;
        }

        push(k);
        _update_val(x, a, b, 2 * k + 1, l, (l + r) / 2);
        _update_val(x, a, b, 2 * k + 2, (l + r) / 2, r);
        update(k);
    }

    ll _query_max(int a, int b, int k, int l, int r) {
        if (b <= l || r <= a) {
            return -inf;
        }
        if (a <= l && r <= b) {
            return max_v[k];
        }
        push(k);
        ll lv = _query_max(a, b, 2 * k + 1, l, (l + r) / 2);
        ll rv = _query_max(a, b, 2 * k + 2, (l + r) / 2, r);
        return max(lv, rv);
    }

    ll _query_min(int a, int b, int k, int l, int r) {
        if (b <= l || r <= a) {
            return inf;
        }
        if (a <= l && r <= b) {
            return min_v[k];
        }
        push(k);
        ll lv = _query_min(a, b, 2 * k + 1, l, (l + r) / 2);
        ll rv = _query_min(a, b, 2 * k + 2, (l + r) / 2, r);
        return min(lv, rv);
    }

    ll _query_sum(int a, int b, int k, int l, int r) {
        if (b <= l || r <= a) {
            return 0;
        }
        if (a <= l && r <= b) {
            return sum[k];
        }
        push(k);
        ll lv = _query_sum(a, b, 2 * k + 1, l, (l + r) / 2);
        ll rv = _query_sum(a, b, 2 * k + 2, (l + r) / 2, r);
        return lv + rv;
    }

public:
    SegmentTree(int n) {
        SegmentTree(n, nullptr);
    }

    SegmentTree(int n, ll* a) : n(n) {
        n0 = 1;
        while (n0 < n) n0 <<= 1;

        for (int i = 0; i < 2 * n0; ++i) ladd[i] = 0, lval[i] = inf;
        len[0] = n0;
        for (int i = 0; i < n0 - 1; ++i) len[2 * i + 1] = len[2 * i + 2] = (len[i] >> 1);

        for (int i = 0; i < n; ++i) {
            max_v[n0 - 1 + i] = min_v[n0 - 1 + i] = sum[n0 - 1 + i] = (a != nullptr ? a[i] : 0);
            smax_v[n0 - 1 + i] = -inf;
            smin_v[n0 - 1 + i] = inf;
            max_c[n0 - 1 + i] = min_c[n0 - 1 + i] = 1;
        }

        for (int i = n; i < n0; ++i) {
            max_v[n0 - 1 + i] = smax_v[n0 - 1 + i] = -inf;
            min_v[n0 - 1 + i] = smin_v[n0 - 1 + i] = inf;
            max_c[n0 - 1 + i] = min_c[n0 - 1 + i] = 0;
        }
        for (int i = n0 - 2; i >= 0; i--) {
            update(i);
        }
    }

    // range minimize query
    void update_min(int a, int b, ll x) {
        _update_min(x, a, b, 0, 0, n0);
    }

    // range maximize query
    void update_max(int a, int b, ll x) {
        _update_max(x, a, b, 0, 0, n0);
    }

    // range add query
    void add_val(int a, int b, ll x) {
        _add_val(x, a, b, 0, 0, n0);
    }

    // range update query
    void update_val(int a, int b, ll x) {
        _update_val(x, a, b, 0, 0, n0);
    }

    // range minimum query
    ll query_max(int a, int b) {
        return _query_max(a, b, 0, 0, n0);
    }

    // range maximum query
    ll query_min(int a, int b) {
        return _query_min(a, b, 0, 0, n0);
    }

    // range sum query
    ll query_sum(int a, int b) {
        return _query_sum(a, b, 0, 0, n0);
    }
};





// @param n `0 <= n`
// @return minimum non-negative `x` s.t. `n <= 2**x`
int ceil_pow2(int n) {
    int x = 0;
    while ((1U << x) < (unsigned int)(n)) x++;
    return x;
}

// @param n `1 <= n`
// @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`
constexpr int bsf_constexpr(unsigned int n) {
    int x = 0;
    while (!(n & (1 << x))) x++;
    return x;
}

// @param n `1 <= n`
// @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`
int bsf(unsigned int n) {
#ifdef _MSC_VER
    unsigned long index;
    _BitScanForward(&index, n);
    return index;
#else
    return __builtin_ctz(n);
#endif
}

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())) {
        log = ceil_pow2(_n);
        size = 1 << log;
        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();
    }
};


int op(int a, int b) { return a + b; }
int e() { return 0; }
int mapping(bool a, int b) {
    if (a == 1) return -b;
    return b;
}
bool composition(bool a, bool b) { return a xor b; }
bool id() { return false; }


//int32_t Q[110000][3];

int main()
{
	using std::endl;
	in.sync_with_stdio(false);
	out.sync_with_stdio(false);
	in.tie(nullptr);
	out.tie(nullptr);

	in >> W_max >> M;
	for (size_t i = 0; i < M; i++)
	{
		in >> X_in[i];
	}
	std::sort(X_in, X_in + M);
    static SegmentTree postree(M, X_in);
    //for (size_t i = 0; i < M; i++)
    //{
    //    postree.add_val(i, i+1, X_in[i]);
    //}
    //for (size_t i = 0; i < M; i++)
    //{
    //    std::cerr << "DEBUG:" << postree.query_sum(i, i + 1) << endl;
    //}

    std::vector<int> one(M, 1);
    lazy_segtree<int, op, e, bool, mapping, composition, id> seg(one);
    // test
    //printf("%d\n", seg.prod(5, 10)); // [5, 10) sum -> 5
    //seg.apply(3, 8, true); // [3, 8)反転
    //printf("%d\n", seg.prod(5, 10)); // [5, 10) sum -> -1 -1 -1 1 1     -> -1
    //seg.apply(7, 10, true); // [7, 10)反転
    //printf("%d\n", seg.prod(5, 10)); // [5, 10) sum -> -1 -1 1 -1 -1     -> -3


    in >> Q;
	for (size_t i = 0; i < Q; i++)
	{
        int type;
        in >> type;
        if (type == 1) {
            int a, b, c;
            in >> a >> b >> c;

            using BS_INT = int64_t;
            BS_INT ok_range = M, ng_range = -1;
            while (std::abs(ok_range - ng_range) > 1) {
                BS_INT mid = (ok_range + ng_range) / 2;
                bool is_ok = false;

                is_ok = a <= postree.query_sum(mid, mid + 1);

                if (is_ok) {
                    ok_range = mid;
                }
                else {
                    ng_range = mid;
                }
            }
            auto a_index = ok_range;

            ok_range = M, ng_range = -1;
            while (std::abs(ok_range - ng_range) > 1) {
                BS_INT mid = (ok_range + ng_range) / 2;
                bool is_ok = false;

                is_ok = b < postree.query_sum(mid, mid + 1);

                if (is_ok) {
                    ok_range = mid;
                }
                else {
                    ng_range = mid;
                }
            }
            auto b_index_end = ok_range;

            postree.add_val(a_index, b_index_end, c);
            postree.update_min(a_index, b_index_end, b);
            postree.update_max(a_index, b_index_end, a);

            seg.apply(a_index, b_index_end, true);
        }
        else {
            int a, b;

            in >> a >> b;

            using BS_INT = int64_t;
            BS_INT ok_range = M, ng_range = -1;
            while (std::abs(ok_range - ng_range) > 1) {
                BS_INT mid = (ok_range + ng_range) / 2;
                bool is_ok = false;

                is_ok = a <= postree.query_sum(mid, mid + 1);

                if (is_ok) {
                    ok_range = mid;
                }
                else {
                    ng_range = mid;
                }
            }
            auto a_index = ok_range;

            ok_range = M, ng_range = -1;
            while (std::abs(ok_range - ng_range) > 1) {
                BS_INT mid = (ok_range + ng_range) / 2;
                bool is_ok = false;

                is_ok = b < postree.query_sum(mid, mid + 1);

                if (is_ok) {
                    ok_range = mid;
                }
                else {
                    ng_range = mid;
                }
            }
            auto b_index_end = ok_range;

            if (M <= a_index) {
                out << 0 << '\n';
            }
            else {
                out << seg.prod(a_index, b_index_end) << '\n';
            }
        }


	}


	return 0;
}
#endif
accuracy: 1
time_ms: 1160
memory_kb: 45260
final_rank: 12

code_snippet: #include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <set>
#include <vector>
#include <numeric>
#include <algorithm>
#include <queue>
#include <string>
#include <random>
#include <array>
#include <climits>
#include <map>
#include <cassert>
template<typename V, typename F, typename P, typename A, typename C>
class LazySeg {
	int log, size;
	std::vector<V> v;
	std::vector<F> f;
	V zero;
	F id;
	P plus;//(left_from, left_until, left_value, right_from, right_until, right_value) -> new_value;
	A apply;//(from, until, func, value) -> new_value;
	C compose;//(from, until, new_func, old_func) -> new_func;
	void apply_range(const int from, const int until) {
		int left = from + (1 << log);
		int right = until + (1 << log);
		for (auto depth = log; depth > 0; --depth) {
			if ((left >> depth << depth) != left) {
				const auto parent = left >> depth;
				const auto l = (parent << depth) - (1 << log);
				const auto m = std::min(size, l + (1 << depth - 1));
				const auto r = std::min(size, l + (1 << depth));
				v[parent << 1] = apply(l, m, f[parent], v[parent << 1]);
				if (m < size) v[(parent << 1) + 1] = apply(m, r, f[parent], v[(parent << 1) + 1]);
				if (depth > 1) {
					f[parent << 1] = compose(l, m, f[parent], f[parent << 1]);
					if (m < size) f[(parent << 1) + 1] = compose(m, r, f[parent], f[(parent << 1) + 1]);
				}
				f[parent] = id;
			}
			if ((right >> depth << depth) != right) {
				const auto parent = right >> depth;
				const auto l = (parent << depth) - (1 << log);
				const auto m = std::min(size, l + (1 << depth - 1));
				const auto r = std::min(size, l + (1 << depth));
				v[parent << 1] = apply(l, m, f[parent], v[parent << 1]);
				if (m < size) v[(parent << 1) + 1] = apply(m, r, f[parent], v[(parent << 1) + 1]);
				if (depth > 1) {
					f[parent << 1] = compose(l, m, f[parent], f[parent << 1]);
					if (m < size) f[(parent << 1) + 1] = compose(m, r, f[parent], f[(parent << 1) + 1]);
				}
				f[parent] = id;
			}
		}
	}
	void accumulate_range(const int from, const int until) {
		const int left = from + (1 << log);
		const int right = until + (1 << log);
		for (auto depth = 1; depth <= log; ++depth) {
			if ((left >> depth << depth) != left) {
				const auto parent = left >> depth;
				const auto l = (parent << depth) - (1 << log);
				const auto m = l + (1 << depth - 1);
				const auto r = std::min(size, l + (1 << depth));
				if (m < size) v[parent] = plus(l, m, v[parent << 1], m, r, v[(parent << 1) + 1]);
				else v[parent] = v[parent << 1];
			}
			if ((right >> depth << depth) != right) {
				const auto parent = right >> depth;
				if (parent == (left >> depth) && (left >> depth << depth) != left) continue;
				const auto l = (parent << depth) - (1 << log);
				const auto m = l + (1 << depth - 1);
				const auto r = std::min(size, l + (1 << depth));
				if (m < size) v[parent] = plus(l, m, v[parent << 1], m, r, v[(parent << 1) + 1]);
				else v[parent] = v[parent << 1];
			}
		}
	}
	static int log2ceil(int value) {
		int result = 0;
		while (value > 1) {
			value = (value + 1) >> 1;
			result += 1;
		}
		return result;
	}
public:
	LazySeg(const int size, const V& zero, const F& id, const P& plus, const A& apply, const C& compose) : log{ log2ceil(size) }, size{ size }, v(2 << log, zero), f(1 << log, id), zero{zero}, id{id}, plus{plus}, apply{apply}, compose{compose}{};
	LazySeg(const std::vector<V>& initial, const V& zero, const F& id, const P& plus, const A& apply, const C& compose) : log{ log2ceil(initial.size()) }, size{ (int)initial.size() }, v(2 << log, zero), f(1 << log, id), zero{ zero }, id{ id }, plus{ plus }, apply{ apply }, compose{ compose }{
		for (auto i = 0; i < initial.size(); ++i) {
			v[i + (1 << log)] = initial[i];
		}
		for (auto d = 1; d <= log; ++d) {
			const auto diff = 1 << (d - 1);
			for (auto i = 0; i < size >> d; ++i) {
				const auto parent = i + (1 << log - d);
				v[parent] = plus(i << d, (i << d) + diff, v[parent << 1], (i << d) + diff, (i + 1) << d, v[(parent << 1) + 1]);
			}
			if (size >> d << d == size) continue;
			const auto parent = (size >> d) + (1 << log - d);
			if (size <= (size >> d << d) + diff) v[parent] = v[parent << 1];
			else v[parent] = plus(size >> d << d, (size >> d << d) + diff, v[parent << 1], (size >> d << d) + diff, size, v[(parent << 1) + 1]);
		}
	};
	V get(const int from, const int until) {
		apply_range(from, until);
		int left = from + (1 << log);
		int right = until + (1 << log);
		int mid{ from };
		V left_result = zero;
		V right_result = zero;
		for (auto depth = 0; depth <= log && left < right; ++depth) {
			if (left & 1) {
				const auto l = (left << depth) - (1 << log);
				const auto r = std::min(size, (left + 1 << depth) - (1 << log));
				left_result = plus(from, l, left_result, l, r, v[left]);
				left += 1;
				mid += 1 << depth;
			}
			if (right & 1) {
				right -= 1;
				const auto l = (right << depth) - (1 << log);
				const auto r = (right + 1 << depth) - (1 << log);
				right_result = plus(l, r, v[right], r, until, right_result);
			}
			left >>= 1;
			right >>= 1;
		}
		return plus(from, mid, left_result, mid, until, right_result);
	}
	void update(const int from, const int until, const F& func) {
		apply_range(from, until);
		int left = from + (1 << log);
		int right = until + (1 << log);
		for (auto depth = 0; depth <= log && left < right; ++depth) {
			if (left & 1) {
				const auto l = (left << depth) - (1 << log);
				const auto r = std::min(size, (left + 1 << depth) - (1 << log));
				if (depth > 0) {
					f[left] = compose(l, r, func, f[left]);
				}
				v[left] = apply(l, r, func, v[left]);
				left += 1;
			}
			if (right & 1) {
				right -= 1;
				const auto l = (right << depth) - (1 << log);
				const auto r = std::min(size, (right + 1 << depth) - (1 << log));
				if (depth > 0) {
					f[right] = compose(l, r, func, f[right]);
				}
				v[right] = apply(l, r, func, v[right]);
			}
			left >>= 1;
			right >>= 1;
		}
		accumulate_range(from, until);
	}
};
class SumBit {
	std::vector<int> vec;
public:
	SumBit(const int size) : vec(size, 0) {};
	int get(int position) const {
		int result = 0;
		while (position >= 0) {
			result += vec[position];
			position -= ~position & (position + 1);
		}
		return result;
	}
	void add(int position, const int value) {
		while (position < vec.size()) {
			vec[position] += value;
			position += ~position & (position + 1);
		}
	}
};
template<typename P>
int first_true(int from, int until, const P& predicate) {
	while (from < until) {
		const auto mid = (from + until) >> 1;
		if (predicate(mid)) {
			until = mid;
		}
		else {
			from = mid + 1;
		}
	}
	return until;
}
int main() {
	int n, m; std::cin >> n >> m;
	std::vector<int> initial(m);
	for (auto& x : initial) {
		std::cin >> x;
	}
	int q; std::cin >> q;
	std::vector<std::vector<int>> queries(q);
	for (auto& query : queries) {
		int t; std::cin >> t;
		if (t == 1) query.resize(3);
		else query.resize(2);
		for (auto& a : query) {
			std::cin >> a;
		}
	}
	std::sort(initial.begin(), initial.end());
	const auto zero = 0;
	const auto id = false;
	const auto plus = [](const int left_from, const int left_until, const int left_value, const int right_from, const int right_until, const int right_value) {
		return left_value + right_value;
	};
	const auto apply = [](const int from, const int until, const bool flip, const int sum) {
		if (flip) return until - from - sum;
		return sum;
	};
	const auto compose = [](const int from, const int until, const bool new_op, const bool old_op) {
		return new_op ^ old_op;
	};
	auto seg = LazySeg(m, zero, id, plus, apply, compose);
	SumBit shift(m);
	for (const auto query : queries) {
		if (query.size() == 3) {
			const auto a = query[0];
			const auto b = query[1];
			const auto c = query[2];
			const auto from = first_true(0, m, [&](const int position) {return a <= shift.get(position) + initial[position]; });
			const auto until = first_true(from, m, [&](const int position) {return b < shift.get(position) + initial[position]; });
			seg.update(from, until, true);
			if (c > 0) {
				const auto mid = first_true(from, until, [&](const int position) {return b - c < shift.get(position) + initial[position]; });
				shift.add(from, c);
				shift.add(mid, -c);
				for (auto i = mid; i < until; ) {
					const auto target = shift.get(i) + initial[i];
					const auto last = first_true(i, until, [&](const int position) {return target < shift.get(position) + initial[position]; });
					if (target != b) {
						shift.add(i, b - target);
						shift.add(last, target - b);
					}
					i = last;
				}
			}
			else {
				const auto mid = first_true(from, until, [&](const int position) {return a - c <= shift.get(position) + initial[position]; });
				shift.add(mid, c);
				shift.add(until, -c);
				for (auto i = from; i < mid; ) {
					const auto target = shift.get(i) + initial[i];
					const auto last = first_true(i, mid, [&](const int position) {return target < shift.get(position) + initial[position]; });
					if (target != a) {
						shift.add(i, a - target);
						shift.add(last, target - a);
					}
					i = last;
				}
			}
		}
		else {
			const auto d = query[0];
			const auto e = query[1];
			const auto from = first_true(0, m, [&](const int position) {return d <= shift.get(position) + initial[position]; });
			const auto until = first_true(from, m, [&](const int position) {return e < shift.get(position) + initial[position]; });
			const auto sum = seg.get(from, until);
			const auto diff = (until - from) - sum * 2;
			std::cout << diff << '\n';
		}
	}
}
accuracy: 1
time_ms: 200
memory_kb: 10432
final_rank: 4

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 100005


struct NA{
	NA(){

		L = R = 0;
		value = 0;
	}
	NA(ll arg_L,ll arg_R,ll arg_value){
		L = arg_L;
		R = arg_R;
		value = arg_value;
	}
	void set(ll arg_L,ll arg_R,ll arg_value){
		L = arg_L;
		R = arg_R;
		value = arg_value;
	}
	ll L,R,value;
};

struct Info{ //■■更新情報■■
	ll L,R,move,num_rev;
	bool FLG;
};

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

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

void first_update(int loc,ll x){
	loc += N-1;

	ans[loc].L = x;
	ans[loc].R = x;
	ans[loc].value = 1;

	if(N == 1)return;

	int parent = (loc-1)/2;

	while(true){

		int l_ch = 2*parent+1;
		int r_ch = 2*parent+2;

		ans[parent].L = min(ans[l_ch].L,ans[r_ch].L);
		ans[parent].R = max(ans[l_ch].R,ans[r_ch].R);
		ans[parent].value = ans[l_ch].value+ans[r_ch].value;

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

void update_info(int node_id,int node_left,int node_right){

	if(!info[node_id].FLG){

		return;
	}

	if(node_right-node_left+1 >= 2){
		/*子に更新情報伝達*/

		ll move = info[node_id].move;

		//左の子
		{
			int L_child = 2*node_id+1;

			info[L_child].L = info[node_id].L;

			if(!info[L_child].FLG){ //子に新しく情報を伝える

				info[L_child].R = ans[L_child].R+move;

			}else{

				info[L_child].R = info[L_child].R+move;
			}

			//■■■■範囲に収める■■■■
			info[L_child].R = max(info[L_child].R,info[node_id].L);
			info[L_child].R = min(info[L_child].R,info[node_id].R);

			info[L_child].move += move;
			info[L_child].num_rev += info[node_id].num_rev;
			info[L_child].FLG = true;
		}

		//右の子
		{
			int R_child = 2*node_id+2;

			info[R_child].R = info[node_id].R;

			if(!info[R_child].FLG){

				info[R_child].L = ans[R_child].L+move;

			}else{

				info[R_child].L =info[R_child].L+move;
			}

			//■■■■範囲に収める■■■■
			info[R_child].L = max(info[R_child].L,info[node_id].L);
			info[R_child].L = min(info[R_child].L,info[node_id].R);

			info[R_child].move += move;
			info[R_child].num_rev += info[node_id].num_rev;
			info[R_child].FLG = true;
		}
	}

	//自分を更新
	ans[node_id].L = info[node_id].L;
	ans[node_id].R = info[node_id].R;
	if((info[node_id].num_rev%2) == 1){

		ans[node_id].value *= -1;
	}

	info[node_id].FLG = false;

	info[node_id].move = 0;
	info[node_id].num_rev = 0;
}


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

	update_info(node_id,node_left,node_right); //旧情報を処理(子に自分の情報を伝える)

	if(update_right < ans[node_id].L || update_left > ans[node_id].R)return;

	if(update_left <= ans[node_id].L && update_right >= ans[node_id].R){ //■ノードの左端と右端の値が、更新の左端値と右端値に完全に含まれていれば更新■

		info[node_id].FLG = true;

		ll L,R;

		L = ans[node_id].L+move;
		R = ans[node_id].R+move;

		//■■■■範囲に収める■■■■
		L = min(L,update_right);
		L = max(L,update_left);

		R = min(R,update_right);
		R = max(R,update_left);


		info[node_id].L = L; //移動後のL
		info[node_id].R = R; //移動後のR

		info[node_id].move = move;
		info[node_id].num_rev = 1;

		update_info(node_id,node_left,node_right); //新情報を処理

		return;

	}else{

		int l_ch = 2*node_id+1;
		int r_ch = 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);

		//■■情報を更新■■
		ans[node_id].L = min(ans[l_ch].L,ans[r_ch].L);
		ans[node_id].R = max(ans[l_ch].R,ans[r_ch].R);
		ans[node_id].value = ans[l_ch].value + ans[r_ch].value;
	}
}

ll query(ll search_left,ll search_right,int node_id,int node_left,int node_right){

	update_info(node_id,node_left,node_right); //旧情報を処理(子に自分の情報を伝える)

	if(search_right < ans[node_id].L || search_left > ans[node_id].R){

		return 0;
	}

	if(search_left <= ans[node_id].L && search_right >= ans[node_id].R){

		return ans[node_id].value;

	}else{

		ll left = query(search_left,search_right,2*node_id+1,node_left,(node_left+node_right)/2);
		ll right = query(search_left,search_right,2*node_id+2,(node_left+node_right)/2+1,node_right);

		int l_ch = 2*node_id+1;
		int r_ch = 2*node_id+2;

		//■■情報を更新■■
		ans[node_id].L = min(ans[l_ch].L,ans[r_ch].L);
		ans[node_id].R = max(ans[l_ch].R,ans[r_ch].R);
		ans[node_id].value = ans[l_ch].value + ans[r_ch].value;

		return left+right;
	}
}


int main(){

	ll maxi;
	int M;
	scanf("%lld %d",&maxi,&M);

	init(M);

	for(int i = 0; i <= 2*N-2; i++){
		info[i].FLG = false;

		ans[i].value = 0;
		ans[i].L = HUGE_NUM;
		ans[i].R = 0;

		info[i].move = 0;
		info[i].num_rev = 0;
	}

	vector<ll> vec;
	ll tmp;
	for(int i = 0; i < M; i++){

		scanf("%lld",&tmp);
		vec.push_back(tmp);
	}
	sort(vec.begin(),vec.end());

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

		first_update(i,vec[i]);
	}


	int num_Q;
	scanf("%d",&num_Q);

	int command;
	ll a,b,c;
	ll d,e;


	for(int loop = 0; loop < num_Q; loop++){

		scanf("%d",&command);
		if(command == 1){

			scanf("%lld %lld %lld",&a,&b,&c);

			//更新処理
			update(a,b,c,0,0,N-1);

		}else{

			scanf("%lld %lld",&d,&e);
			//出力処理
			printf("%lld\n",query(d,e,0,0,N-1));
		}
	}

	return 0;
}
accuracy: 1
time_ms: 170
memory_kb: 28220
final_rank: 9

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 100005


struct NA{
	NA(){

		L = R = 0;
		value = 0;
	}
	NA(ll arg_L,ll arg_R,ll arg_value){
		L = arg_L;
		R = arg_R;
		value = arg_value;
	}
	void set(ll arg_L,ll arg_R,ll arg_value){
		L = arg_L;
		R = arg_R;
		value = arg_value;
	}
	ll L,R,value;
};

struct Info{ //■■更新情報■■
	ll L,R,move,num_rev;
	bool FLG;
};

int N = 1;
Info info[6*SIZE];
NA ans[6*SIZE];
bool broken[6*SIZE];

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

void first_update(int loc,ll x){
	loc += N-1;

	ans[loc].L = x;
	ans[loc].R = x;
	ans[loc].value = 1;

	if(N == 1)return;

	int parent = (loc-1)/2;

	while(true){

		int l_ch = 2*parent+1;
		int r_ch = 2*parent+2;

		ans[parent].L = min(ans[l_ch].L,ans[r_ch].L);
		ans[parent].R = max(ans[l_ch].R,ans[r_ch].R);
		ans[parent].value = ans[l_ch].value+ans[r_ch].value;

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

void update_info(int node_id,int node_left,int node_right){

	if(!info[node_id].FLG){

		return;
	}

	if(node_right-node_left+1 >= 2){
		/*子に更新情報伝達*/

		ll move = info[node_id].move;

		//左の子
		{
			int L_child = 2*node_id+1;

			info[L_child].L = info[node_id].L;

			if(!info[L_child].FLG){ //子に新しく情報を伝える

				info[L_child].R = ans[L_child].R+move;

			}else{

				info[L_child].R = info[L_child].R+move;
			}

			//■■■■範囲に収める■■■■
			info[L_child].R = max(info[L_child].R,info[node_id].L);
			info[L_child].R = min(info[L_child].R,info[node_id].R);

			info[L_child].move += move;
			info[L_child].num_rev += info[node_id].num_rev;
			info[L_child].FLG = true;
		}

		//右の子
		{
			int R_child = 2*node_id+2;

			info[R_child].R = info[node_id].R;

			if(!info[R_child].FLG){

				info[R_child].L = ans[R_child].L+move;

			}else{

				info[R_child].L =info[R_child].L+move;
			}

			//■■■■範囲に収める■■■■
			info[R_child].L = max(info[R_child].L,info[node_id].L);
			info[R_child].L = min(info[R_child].L,info[node_id].R);

			info[R_child].move += move;
			info[R_child].num_rev += info[node_id].num_rev;
			info[R_child].FLG = true;
		}
	}

	//自分を更新
	ans[node_id].L = info[node_id].L;
	ans[node_id].R = info[node_id].R;
	if((info[node_id].num_rev%2) == 1){

		ans[node_id].value *= -1;
	}

	info[node_id].FLG = false;

	info[node_id].move = 0;
	info[node_id].num_rev = 0;
}


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

	update_info(node_id,node_left,node_right); //旧情報を処理(子に自分の情報を伝える)

	if(update_right < ans[node_id].L || update_left > ans[node_id].R)return;

	if(update_left <= ans[node_id].L && update_right >= ans[node_id].R){

		info[node_id].FLG = true;

		ll L,R;

		L = ans[node_id].L+move;
		R = ans[node_id].R+move;

		//■■■■範囲に収める■■■■
		L = min(L,update_right);
		L = max(L,update_left);

		R = min(R,update_right);
		R = max(R,update_left);


		info[node_id].L = L; //移動後のL
		info[node_id].R = R; //移動後のR

		info[node_id].move = move;
		info[node_id].num_rev = 1;

		update_info(node_id,node_left,node_right); //新情報を処理

		return;

	}else{

		int l_ch = 2*node_id+1;
		int r_ch = 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);

		ans[node_id].L = min(ans[l_ch].L,ans[r_ch].L);
		ans[node_id].R = max(ans[l_ch].R,ans[r_ch].R);
		ans[node_id].value = ans[l_ch].value + ans[r_ch].value;
	}
}

ll query(ll search_left,ll search_right,int node_id,int node_left,int node_right){

	update_info(node_id,node_left,node_right); //旧情報を処理(子に自分の情報を伝える)

	if(search_right < ans[node_id].L || search_left > ans[node_id].R){

		return 0;

	}

	if(search_left <= ans[node_id].L && search_right >= ans[node_id].R){


		return ans[node_id].value;

	}else{

		ll left = query(search_left,search_right,2*node_id+1,node_left,(node_left+node_right)/2);
		ll right = query(search_left,search_right,2*node_id+2,(node_left+node_right)/2+1,node_right);

		int l_ch = 2*node_id+1;
		int r_ch = 2*node_id+2;

		ans[node_id].L = min(ans[l_ch].L,ans[r_ch].L);
		ans[node_id].R = max(ans[l_ch].R,ans[r_ch].R);
		ans[node_id].value = ans[l_ch].value + ans[r_ch].value;

		return left+right;
	}
}


int main(){

	ll maxi;
	int M;
	scanf("%lld %d",&maxi,&M);

	init(M);

	for(int i = 0; i <= 2*N-2; i++){
		info[i].FLG = false;

		ans[i].value = 0;
		ans[i].L = HUGE_NUM;
		ans[i].R = 0;

		info[i].move = 0;
		info[i].num_rev = 0;
	}

	vector<ll> vec;
	ll tmp;
	for(int i = 0; i < M; i++){

		scanf("%lld",&tmp);
		vec.push_back(tmp);
	}
	sort(vec.begin(),vec.end());

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

		first_update(i,vec[i]);
	}


	int num_Q;
	scanf("%d",&num_Q);

	int command;
	ll a,b,c;
	ll d,e;


	for(int loop = 0; loop < num_Q; loop++){

		scanf("%d",&command);
		if(command == 1){

			scanf("%lld %lld %lld",&a,&b,&c);

			//更新処理
			update(a,b,c,0,0,N-1);

		}else{

			scanf("%lld %lld",&d,&e);
			//出力処理
			printf("%lld\n",query(d,e,0,0,N-1));
		}
	}

	return 0;
}
accuracy: 1
time_ms: 180
memory_kb: 28224
final_rank: 10

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 100005


struct NA{
	NA(){

		L = R = 0;
		value = 0;
	}
	NA(ll arg_L,ll arg_R,ll arg_value){
		L = arg_L;
		R = arg_R;
		value = arg_value;
	}
	void set(ll arg_L,ll arg_R,ll arg_value){
		L = arg_L;
		R = arg_R;
		value = arg_value;
	}
	ll L,R,value;
};

struct Info{ //■■更新情報■■
	ll L,R,move,num_rev;
	bool FLG;
};

int N = 1;
Info info[6*SIZE];
NA ans[6*SIZE];
bool broken[6*SIZE];

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

void first_update(int loc,ll x){
	loc += N-1;

	ans[loc].L = x;
	ans[loc].R = x;
	ans[loc].value = 1;

	if(N == 1)return;

	int parent = (loc-1)/2;

	while(true){

		int l_ch = 2*parent+1;
		int r_ch = 2*parent+2;

		ans[parent].L = min(ans[l_ch].L,ans[r_ch].L);
		ans[parent].R = max(ans[l_ch].R,ans[r_ch].R);
		ans[parent].value = ans[l_ch].value+ans[r_ch].value;

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

void update_info(int node_id,int node_left,int node_right){

	if(!info[node_id].FLG){

		return;
	}

	if(node_right-node_left+1 >= 2){
		/*子に更新情報伝達*/

		ll move = info[node_id].move;

		//左の子
		{
			int L_child = 2*node_id+1;

			info[L_child].L = info[node_id].L;

			if(!info[L_child].FLG){ //子に新しく情報を伝える

				if(move >= 0){

					info[L_child].R = min(info[node_id].R,ans[L_child].R+move);
				}else{

					info[L_child].R = max(info[node_id].L,ans[L_child].R+move);
				}

				info[L_child].move = move;
				info[L_child].num_rev = info[node_id].num_rev;

			}else{

				if(move >= 0){

					info[L_child].R = min(info[node_id].R,info[L_child].R+move);
				}else{

					info[L_child].R = max(info[node_id].L,info[L_child].R+move);
				}

				info[L_child].move += move;
				info[L_child].num_rev += info[node_id].num_rev;
			}

			info[L_child].FLG = true;
		}

		//右の子
		{
			int R_child = 2*node_id+2;

			info[R_child].R = info[node_id].R;

			if(!info[R_child].FLG){

				if(move >= 0){

					info[R_child].L = min(info[node_id].R,ans[R_child].L+move);
				}else{

					info[R_child].L = max(info[node_id].L,ans[R_child].L+move);
				}

				info[R_child].move = move;
				info[R_child].num_rev = info[node_id].num_rev;

			}else{

				if(move >= 0){

					info[R_child].L = min(info[node_id].R,info[R_child].L+move);
				}else{

					info[R_child].L = max(info[node_id].L,info[R_child].L+move);
				}

				info[R_child].move += move;
				info[R_child].num_rev += info[node_id].num_rev;
			}

			info[R_child].FLG = true;
		}
	}

	//自分を更新
	ans[node_id].L = info[node_id].L;
	ans[node_id].R = info[node_id].R;
	if((info[node_id].num_rev%2) == 1){

		ans[node_id].value *= -1;
	}

	info[node_id].FLG = false;
	//broken[node_id] = false;

	info[node_id].move = 0;
	info[node_id].num_rev = 0;
}


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

	update_info(node_id,node_left,node_right); //旧情報を処理(子に自分の情報を伝える)

	if(update_right < ans[node_id].L || update_left > ans[node_id].R)return;

	if(update_left <= ans[node_id].L && update_right >= ans[node_id].R){

		info[node_id].FLG = true;

		ll L,R;

		L = ans[node_id].L+move;
		R = ans[node_id].R+move;

		//範囲内に収める
		L = min(L,update_right);
		L = max(L,update_left);

		R = min(R,update_right);
		R = max(R,update_left);


		info[node_id].L = L; //移動後のL
		info[node_id].R = R; //移動後のR
		info[node_id].move = move;
		info[node_id].num_rev = 1;

		update_info(node_id,node_left,node_right); //新情報を処理

		return;

	}else{

		broken[node_id] = true;

		int l_ch = 2*node_id+1;
		int r_ch = 2*node_id+2;

		ans[node_id].L = -HUGE_NUM;
		ans[node_id].R = HUGE_NUM;

		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);
/*
		ans[node_id].L = min(ans[l_ch].L,ans[r_ch].L);
		ans[node_id].R = max(ans[l_ch].R,ans[r_ch].R);
		ans[node_id].value = ans[l_ch].value + ans[r_ch].value;*/
	}
}

ll query(ll search_left,ll search_right,int node_id,int node_left,int node_right){

	update_info(node_id,node_left,node_right); //旧情報を処理(子に自分の情報を伝える)

	if(search_right < ans[node_id].L || search_left > ans[node_id].R){

		return 0;

	}

	if(search_left <= ans[node_id].L && search_right >= ans[node_id].R){


		return ans[node_id].value;

	}else{

		ll left = query(search_left,search_right,2*node_id+1,node_left,(node_left+node_right)/2);
		ll right = query(search_left,search_right,2*node_id+2,(node_left+node_right)/2+1,node_right);

		int l_ch = 2*node_id+1;
		int r_ch = 2*node_id+2;

		/*ans[node_id].L = min(ans[l_ch].L,ans[r_ch].L);
		ans[node_id].R = max(ans[l_ch].R,ans[r_ch].R);
		ans[node_id].value = ans[l_ch].value + ans[r_ch].value;
*/
		return left+right;
	}
}


int main(){

	ll maxi;
	int M;
	scanf("%lld %d",&maxi,&M);

	init(M);

	for(int i = 0; i <= 2*N-2; i++){
		info[i].FLG = false;

		ans[i].value = 0;
		ans[i].L = HUGE_NUM;
		ans[i].R = 0;

		info[i].move = 0;
		info[i].num_rev = 0;
	}

	vector<ll> vec;
	ll tmp;
	for(int i = 0; i < M; i++){

		scanf("%lld",&tmp);
		vec.push_back(tmp);
	}
	sort(vec.begin(),vec.end());

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

		first_update(i,vec[i]);
	}


	int num_Q;
	scanf("%d",&num_Q);

	int command;
	ll a,b,c;
	ll d,e;

	for(int loop = 0; loop < num_Q; loop++){

		scanf("%d",&command);
		if(command == 1){

			scanf("%lld %lld %lld",&a,&b,&c);

			//更新処理
			update(a,b,c,0,0,N-1);


		}else{

			scanf("%lld %lld",&d,&e);
			//出力処理
			printf("%lld\n",query(d,e,0,0,N-1));
		}
	}

	return 0;
}
accuracy: 0.4583333333333333
time_ms: 70
memory_kb: 19364
final_rank: 16

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 100005


struct NA{
	NA(){

		L = R = 0;
		value = 0;
	}
	NA(ll arg_L,ll arg_R,ll arg_value){
		L = arg_L;
		R = arg_R;
		value = arg_value;
	}
	void set(ll arg_L,ll arg_R,ll arg_value){
		L = arg_L;
		R = arg_R;
		value = arg_value;
	}
	ll L,R,value;
};

struct Info{ //■■更新情報■■
	ll L,R,move,num_rev;
	bool FLG;
};

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

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

void first_update(int loc,ll x){
	loc += N-1;

	ans[loc].L = x;
	ans[loc].R = x;
	ans[loc].value = 1;

	if(N == 1)return;

	int parent = (loc-1)/2;

	while(true){

		int l_ch = 2*parent+1;
		int r_ch = 2*parent+2;

		ans[parent].L = min(ans[l_ch].L,ans[r_ch].L);
		ans[parent].R = max(ans[l_ch].R,ans[r_ch].R);
		ans[parent].value = ans[l_ch].value+ans[r_ch].value;

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

void update_info(int node_id,int node_left,int node_right){

	if(!info[node_id].FLG){

		return;
	}

	if(node_right-node_left+1 >= 2){
		/*子に更新情報伝達*/

		ll move = info[node_id].move;

		//左の子
		{
			int L_child = 2*node_id+1;

			info[L_child].L = info[node_id].L;

			if(!info[L_child].FLG){ //子に新しく情報を伝える

				if(move >= 0){

					info[L_child].R = min(info[node_id].R,ans[L_child].R+move);
				}else{

					info[L_child].R = max(info[node_id].L,ans[L_child].R+move);
				}

				info[L_child].move = move;
				info[L_child].num_rev = info[node_id].num_rev;

			}else{

				if(move >= 0){

					info[L_child].R = min(info[node_id].R,info[L_child].R+move);
				}else{

					info[L_child].R = max(info[node_id].L,info[L_child].R+move);
				}

				info[L_child].move += move;
				info[L_child].num_rev += info[node_id].num_rev;
			}

			info[L_child].FLG = true;
		}

		//右の子
		{
			int R_child = 2*node_id+2;

			info[R_child].R = info[node_id].R;

			if(!info[R_child].FLG){

				if(move >= 0){

					info[R_child].L = min(info[node_id].R,ans[R_child].L+move);
				}else{

					info[R_child].L = max(info[node_id].L,ans[R_child].L+move);
				}

				info[R_child].move = move;
				info[R_child].num_rev = info[node_id].num_rev;

			}else{

				if(move >= 0){

					info[R_child].L = min(info[node_id].R,info[R_child].L+move);
				}else{

					info[R_child].L = max(info[node_id].L,info[R_child].L+move);
				}

				info[R_child].move += move;
				info[R_child].num_rev += info[node_id].num_rev;
			}

			info[R_child].FLG = true;
		}
	}

	//自分を更新
	ans[node_id].L = info[node_id].L;
	ans[node_id].R = info[node_id].R;
	if((info[node_id].num_rev%2) == 1){

		ans[node_id].value *= -1;
	}

	info[node_id].FLG = false;
	//broken[node_id] = false;

	info[node_id].move = 0;
	info[node_id].num_rev = 0;
}


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

	update_info(node_id,node_left,node_right); //旧情報を処理(子に自分の情報を伝える)

	if(update_right < ans[node_id].L || update_left > ans[node_id].R)return;

	if(update_left <= ans[node_id].L && update_right >= ans[node_id].R){

		info[node_id].FLG = true;

		ll L,R;

		if(move >= 0){ //右へ動く

			L = min(update_right,ans[node_id].L+move);
			R = min(update_right,ans[node_id].R+move);

		}else{ //左へ動く

			L = max(update_left,ans[node_id].L+move);
			R = max(update_left,ans[node_id].R+move);
		}

		info[node_id].L = L; //移動後のL
		info[node_id].R = R; //移動後のR
		info[node_id].move = move;
		info[node_id].num_rev = 1;

		update_info(node_id,node_left,node_right); //新情報を処理

		return;

	}else{

		ans[node_id].L = -HUGE_NUM;
		ans[node_id].R = HUGE_NUM;

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

	}
}

ll query(ll search_left,ll search_right,int node_id,int node_left,int node_right){

	update_info(node_id,node_left,node_right); //旧情報を処理(子に自分の情報を伝える)

	if(search_right < ans[node_id].L || search_left > ans[node_id].R){

		return 0;

	}

	if(search_left <= ans[node_id].L && search_right >= ans[node_id].R && ans[node_id].L != -HUGE_NUM){


		return ans[node_id].value;

	}else{

		ll left = query(search_left,search_right,2*node_id+1,node_left,(node_left+node_right)/2);
		ll right = query(search_left,search_right,2*node_id+2,(node_left+node_right)/2+1,node_right);

		return left+right;
	}
}


int main(){

	ll maxi;
	int M;
	scanf("%lld %d",&maxi,&M);

	init(M);

	for(int i = 0; i <= 2*N-2; i++){
		info[i].FLG = false;

		ans[i].value = 0;
		ans[i].L = HUGE_NUM;
		ans[i].R = 0;

		info[i].move = 0;
		info[i].num_rev = 0;
	}

	vector<ll> vec;
	ll tmp;
	for(int i = 0; i < M; i++){

		scanf("%lld",&tmp);
		vec.push_back(tmp);
	}
	sort(vec.begin(),vec.end());

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

		first_update(i,vec[i]);
	}


	int num_Q;
	scanf("%d",&num_Q);

	int command;
	ll a,b,c;
	ll d,e;

	for(int loop = 0; loop < num_Q; loop++){

		scanf("%d",&command);
		if(command == 1){

			scanf("%lld %lld %lld",&a,&b,&c);

			//更新処理
			update(a,b,c,0,0,N-1);


		}else{

			scanf("%lld %lld",&d,&e);
			//出力処理
			printf("%lld\n",query(d,e,0,0,N-1));
		}
	}

	return 0;
}
accuracy: 0.4583333333333333
time_ms: 60
memory_kb: 17896
final_rank: 15