#pragma comment(linker, "/stack:200000000") #pragma GCC optimize("Ofast", "unroll-loops", "omit-frame-pointer", "inline") #pragma GCC option("arch=native","tune=native","no-zero-upper") #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native,avx2") #include #define LL long long int #define ULL unsigned LL #define LD long double #define FI first #define SE second #define PB push_back #define PF push_front #define V vector #define PQ priority_queue #define ALL(x) x.begin(), x.end() #define SZ(x) (int)(x).size() #define FORI(i, a, b) for(int i = a; i < b ; ++i) #define FORD(i, a, b) for(int i = a; i > b ; --i) using namespace std; using pii = pair; struct Update { int l, r, delta, resigns; bool operator < (const Update& other) const { return l == other.l ? r < other.r : l < other.l; } }; const int N = 1e5 + 100; LL t[4*N]; void build(const V& a, int v, int tl, int tr){ if (tl == tr) t[v] = a[tl]; else { int tm = (tl + tr) / 2; build (a, v*2, tl, tm); build (a, v*2+1, tm+1, tr); t[v] = t[v*2] + t[v*2+1]; } } LL sum(int v, int tl, int tr, int l, int r){ if (l > r) return 0; if (l == tl && r == tr) return t[v]; int tm = (tl + tr) / 2; return sum(v*2, tl, tm, l, min(r,tm)) + sum(v*2+1, tm+1, tr, max(l,tm+1), r); } void update(int v, int tl, int tr, int pos, LL new_val){ if (tl == tr) t[v] = new_val; else { int tm = (tl + tr) / 2; if (pos <= tm) update(v*2, tl, tm, pos, new_val); else update(v*2+1, tm+1, tr, pos, new_val); t[v] = t[v*2] + t[v*2+1]; } } int main(){ ifstream cin("accounting.in"); ofstream cout("accounting.out"); // ios_base::sync_with_stdio(false); // cin.tie(NULL); // cout.tie(NULL); mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); clock_t start_t = clock(); int n, q; cin >> n >> q; V a(n); FORI(i,0,n){ cin >> a[i]; } build(a, 1, 0, n-1); int k = sqrt(n); set segs; while(q--){ char t; int l, r, x; cin >> t >> l >> r; --l; --r; if (t == '-'){ cin >> x; while(l <= r){ auto it = segs.lower_bound({l+1, 0, 0, 0}); if (it == segs.begin()){ segs.insert({l, min(r, it == segs.end() ? r : it->l-1), x, 1}); l = min(r, it == segs.end() ? r : it->l-1) + 1; continue; } if ((--it)->r < l){ ++it; segs.insert({l, min(r, it == segs.end() ? r : it->l-1), x, 1}); l = min(r, it == segs.end() ? r : it->l-1) + 1; continue; } auto seg = *it; segs.erase(it); if (seg.l < l) segs.insert({seg.l, l-1, seg.delta, seg.resigns}); segs.insert({l, min(r, seg.r), x - seg.delta, seg.resigns + 1}); if (r < seg.r) segs.insert({r+1, seg.r, seg.delta, seg.resigns}); l = min(r, seg.r) + 1; } queue rem; for(auto seg: segs){ // cout << seg.l << ' ' << seg.r << ' ' << seg.delta << ' ' << seg.resigns << endl; if (seg.r - seg.l < k){ FORI(i,seg.l,seg.r+1){ a[i] = seg.delta + ((seg.resigns & 1) ? -a[i] : a[i]); update(1, 0, n-1, i, a[i]); } rem.push(seg); } } while(!rem.empty()){ segs.erase(rem.front()); rem.pop(); } } else { auto it = segs.lower_bound({l+1, 0, 0, 0}); if (it != segs.begin()){ --it; if (it->r < l) ++it; } LL ans = sum(1, 0, n-1, l, min(r, it == segs.end() ? r : it->l-1)); // cout << l << ' ' << min(r, it == segs.end() ? r : it->l-1) << " -> " << ans << endl; l = min(r, max(l-1, it == segs.end() ? r : it->l-1)) + 1; while(it != segs.end() && it->l <= r){ LL s = sum(1, 0, n-1, l, min(r, it->r)); LL add = (min(r, it->r) - l + 1) * it->delta + ((it->resigns & 1) ? -s : s); // cout << l << ' ' << min(r, it->r) << " -> " << it->delta << ", " << it->resigns << " = " << add << endl; ans += add; l = it->r + 1; ++it; } ans += sum(1, 0, n-1, l, r); cout << ans << '\n'; } } return 0; }