結果
| 問題 | No.1441 MErGe | 
| コンテスト | |
| ユーザー |  | 
| 提出日時 | 2020-11-26 17:11:14 | 
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) | 
| 結果 | 
                                AC
                                 
                             | 
| 実行時間 | 333 ms / 1,000 ms | 
| コード長 | 2,695 bytes | 
| コンパイル時間 | 2,635 ms | 
| コンパイル使用メモリ | 208,880 KB | 
| 最終ジャッジ日時 | 2025-01-16 05:50:48 | 
| ジャッジサーバーID (参考情報) | judge3 / judge2 | 
(要ログイン)
| ファイルパターン | 結果 | 
|---|---|
| sample | AC * 2 | 
| other | AC * 28 | 
ソースコード
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using VI = vector<int>;
using VL = vector<ll>;
#define FOR(i,a,n) for(int i=(a);i<(n);++i)
#define tp(a,i) get<i>(a)
inline void init() { cin.tie(nullptr); cout.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(15); }
template<class T>inline istream& operator>>(istream& is, vector<T>& v) { for (auto& a : v)is >> a; return is; }
template<class T>inline void print(const T& a) { cout << a << "\n"; }
template<class T>inline void print(const vector<T>& v) { for (int i = 0; i < v.size(); ++i)cout << v[i] << (i == v.size() - 1 ? "\n" : " "); }
template<class T>inline T sum(const vector<T>& a, int l, int r) { return a[r] - (l == 0 ? 0 : a[l - 1]); }
template<class Op> class SegmentTree {
	using T = typename Op::T;
	int len, n;
	vector<T> dat;
	vector<pair<int, int>> range;
public:
	SegmentTree(const vector<T>& v) : n(v.size()) {
		for (len = 1; len < n; len <<= 1);
		dat.resize(len << 1, Op::unit);
		range.resize(len << 1);
		for (int i = 0; i < n; ++i)dat[i + len] = v[i];
		for (int i = 0; i < len; ++i)
			range[i + len] = make_pair(i, i + 1);
		for (int i = len - 1; 0 < i; --i) {
			dat[i] = Op::merge(dat[i << 1], dat[i << 1 | 1]);
			range[i] = make_pair(range[i << 1].first, range[i << 1 | 1].second);
		}
	}
	inline void update(int idx, const T a) {
		idx += len;
		dat[idx] = Op::update(dat[idx], a);
		for (idx >>= 1; 0 < idx; idx >>= 1)
			dat[idx] = Op::merge(dat[idx << 1], dat[idx << 1 | 1]);
	}
	inline int binary_search(const T a) {
		if (!Op::check(dat[1], a))return n;
		T cur = Op::unit;
		int idx = 2;
		for (; idx < len << 1; idx <<= 1) {
			if (!Op::check(Op::merge(cur, dat[idx]), a))
				cur = Op::merge(cur, dat[idx++]);
		}
		return min((idx >> 1) - len, n);
	}
};
template<class Type> struct node {
	using T = Type;
	inline static T unit = 0;
	inline static T merge(T vl, T vr) { return vl + vr; }
	inline static T update(T vl, T vr) { return vl + vr; }
	inline static T check(T vl, T vr) { return vl >= vr; }
};
int main() {
    init();
    int n, q; cin >> n >> q;
    VL a(n); cin >> a;
    SegmentTree<node<int>> seg(VI(n, 1));
    set<int> s;
    FOR(i, 0, n) {
        if (0 < i)a[i] += a[i - 1];
        s.emplace(i);
    }
    while (q--) {
        int t, l, r; cin >> t >> l >> r;
        if (t == 1) {
            int d = r - l;
            l = seg.binary_search(l);
            r = seg.binary_search(r);
            auto it = s.find(l);
            FOR(i, 0, d)seg.update(*++it, -1);
            FOR(i, 0, d)s.erase(s.upper_bound(l));
        }
        else cout << sum(a, seg.binary_search(l), seg.binary_search(r + 1) - 1) << "\n";
    }
    return 0;
}
            
            
            
        