#ifndef ONLINE_JUDGE #include "header.hpp" #else #include #include #include using cpp_int=boost::multiprecision::cpp_int; #include templateusing cpp_float=boost::multiprecision::number>; templateusing cpp_double=boost::multiprecision::number>; #endif using namespace std; using ll=long long; inline void yn(bool x){if(x){cout<<"Yes"< inline void erase_duplicate(vector& A){sort(A.begin(),A.end());A.erase(unique(A.begin(),A.end()),A.end());} inline ll powll(ll x,ll n){ll r=1;while(n>0){if(n&1){r*=x;};x*=x;n>>=1;};return r;} // https://hackmd.io/@tatyam-prime/DualSegmentTree using ll = long long; template bool chmin(T& a, const T& b){ if(a > b){ a = b; return 1; } return 0; } template struct DualSegmentTree{ virtual void c(T&, const T&) = 0; ll size = 1, rank = 0; vector 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& 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); } } }; template struct RAQ : DualSegmentTree{ using Base = DualSegmentTree; void c(T& a, const T& b){ a += b; } RAQ(ll n, const T& def_value = T(), const T& def_lazy = T()) : Base(n, def_value, def_lazy){} RAQ(const vector& v, const T& def_lazy = T()) : Base(v, def_lazy){} }; template struct RUQ : DualSegmentTree{ using Base = DualSegmentTree; void c(T& a, const T& b){ a = b; } RUQ(ll n, const T& def_value, const T& def_lazy = numeric_limits::max()) : Base(n, def_value, def_lazy){} RUQ(const vector& v, const T& def_lazy = numeric_limits::max()) : Base(v, def_lazy){} }; template struct RchmQ : DualSegmentTree{ using Base = DualSegmentTree; void c(T& a, const T& b){ chmin(a, b); } RchmQ(ll n, const T& def_value, const T& def_lazy = numeric_limits::max()) : Base(n, def_value, def_lazy){} RchmQ(const vector& v, const T& def_lazy = numeric_limits::max()) : Base(v, def_lazy){} }; ll op(ll a,ll b){ return a+b; } ll e(){ return 0LL; } int main(){ ll N,Q; cin>>N>>Q; vector A(N); for(ll i=0;i>A[i]; } RAQ seg1(A); atcoder::segtree seg2(N-1); for(ll i=0;i>t; if(t==1){ ll l,r,x; cin>>l>>r>>x; l--; seg1.query(l,r,x); if(l-1>=0){ if(seg1[l]==seg1[l-1]){ seg2.set(l-1,0); }else{ seg2.set(l-1,1); } } if(r>l>>r; l--; cout<