結果

問題 No.3265 地元に帰れば天才扱い!
ユーザー yuuDot
提出日時 2025-09-06 15:42:34
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 1,335 ms / 2,500 ms
コード長 6,944 bytes
コンパイル時間 4,454 ms
コンパイル使用メモリ 210,088 KB
実行使用メモリ 28,300 KB
最終ジャッジ日時 2025-09-06 15:43:12
合計ジャッジ時間 34,358 ms
ジャッジサーバーID
(参考情報)
judge3 / judge
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 4
other AC * 21
権限があれば一括ダウンロードができます

ソースコード

diff #

/*
from atcoder.lazysegtree import LazySegTree
from atcoder.segtree import SegTree

n, m = map(int, input().split())
rate = [0] * m
each_range = [(0, 0)] * m
pos = [0] * m
ID = 0


# (sum, length)
def op(x, y):
    return (x[0] + y[0], x[1] + y[1])


def e():
    return (0, 0)


def mapping(f, x):
    if f == ID:
        return x
    return (f * x[1] + x[0], x[1])


def composition(f_new, f_old):
    if f_new == ID:
        return f_old
    return f_new + f_old


lst = LazySegTree(op, e(), mapping, composition, ID, [(0, 1)] * m)
for i in range(n):
    a, l, r = map(int, input().split())
    rate[i] = a
    pos[i] = i
    each_range[i] = (l, r)
    lst.apply(l - 1, r, 1)

# for i in range(m):
#     print(lst.get(i), end=" ")
# exit()

st = SegTree(lambda x, y: x + y, 0, rate)
crr_ans = 0
for i in range(m):
    if rate[i] == 0:
        continue
    l, r = each_range[i]
    crr_ans += rate[i] * (r - l + 1) - st.prod(l - 1, r)

ans = []
q = int(input())
for _ in range(q):
    x, y, u, v = map(int, input().split())
    x -= 1
    y -= 1

    px = pos[x]
    # 何人の範囲にかぶっていたか
    l, r = each_range[px]
    minus = lst.get(px)[0]
    if l - 1 <= px < r:
        minus -= 1
    crr_ans += rate[px] * minus
    lst.apply(l - 1, r, -1)

    # 引っ越す前の本人の天才度
    crr_ans -= rate[px] * (r - l + 1) - st.prod(l - 1, r)

    # レート更新とか
    rate[y] = rate[px]
    rate[px] = 0
    st.set(px, 0)
    st.set(y, rate[y])
    each_range[px] = (0, 0)
    each_range[y] = (u, v)

    # 何人の範囲にかぶっているか
    crr_ans -= rate[y] * lst.get(y)[0]
    lst.apply(u - 1, v, 1)

    # 引っ越した後の天才度
    crr_ans += rate[y] * (v - u + 1) - st.prod(u - 1, v)

    pos[x] = y
    ans.append(crr_ans)

print(*ans, sep="\n")
*/

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

using ll = long long;
struct Node {
    ll sum;
    ll len;
    Node(): sum(0), len(0) {}
    Node(ll s, ll l): sum(s), len(l) {}
};

struct LazySegTree {
    int n;
    int size_;
    vector<Node> seg;
    vector<ll> lazy;
    const ll ID = 0;

    LazySegTree() { n = 0; size_ = 0; }

    Node op(const Node &a, const Node &b) {
        return Node(a.sum + b.sum, a.len + b.len);
    }
    Node e() { return Node(0, 0); }

    Node mapping(ll f, const Node &x) {
        if (f == ID) return x;
        return Node(f * x.len + x.sum, x.len);
    }
    ll composition(ll f_new, ll f_old) {
        if (f_new == ID) return f_old;
        return f_new + f_old;
    }

    void build(const vector<Node> &v) {
        n = (int)v.size();
        size_ = 1;
        while (size_ < n) size_ <<= 1;
        seg.assign(2 * size_, e());
        lazy.assign(2 * size_, ID);
        for (int i = 0; i < n; ++i) seg[size_ + i] = v[i];
        for (int i = size_ - 1; i >= 1; --i) seg[i] = op(seg[2*i], seg[2*i+1]);
    }

    void push(int k) {
        if (lazy[k] != ID && k < size_) {
            ll f = lazy[k];
            int lc = 2*k, rc = 2*k+1;
            seg[lc] = mapping(f, seg[lc]);
            seg[rc] = mapping(f, seg[rc]);
            lazy[lc] = composition(f, lazy[lc]);
            lazy[rc] = composition(f, lazy[rc]);
            lazy[k] = ID;
        }
    }

    void range_apply(int a, int b, ll f) { range_apply(a, b, f, 1, 0, size_); }

    void range_apply(int a, int b, ll f, int k, int l, int r) {
        if (a >= r || b <= l) return;
        if (a <= l && r <= b) {
            seg[k] = mapping(f, seg[k]);
            lazy[k] = composition(f, lazy[k]);
            return;
        }
        push(k);
        int mid = (l + r) >> 1;
        range_apply(a, b, f, 2*k, l, mid);
        range_apply(a, b, f, 2*k+1, mid, r);
        seg[k] = op(seg[2*k], seg[2*k+1]);
    }

    Node prod(int a, int b) { return prod(a, b, 1, 0, size_); }

    Node prod(int a, int b, int k, int l, int r) {
        if (a >= r || b <= l) return e();
        if (a <= l && r <= b) return seg[k];
        push(k);
        int mid = (l + r) >> 1;
        return op(prod(a, b, 2*k, l, mid), prod(a, b, 2*k+1, mid, r));
    }

    Node get(int idx) { return prod(idx, idx+1); }
};

struct SegTree {
    int n;
    int size_;
    vector<ll> seg;
    ll e = 0;

    SegTree() { n = 0; size_ = 0; }

    void build(const vector<ll> &v) {
        n = (int)v.size();
        size_ = 1;
        while (size_ < n) size_ <<= 1;
        seg.assign(2 * size_, e);
        for (int i = 0; i < n; ++i) seg[size_ + i] = v[i];
        for (int i = size_ - 1; i >= 1; --i) seg[i] = seg[2*i] + seg[2*i+1];
    }

    void set(int idx, ll val) {
        int k = size_ + idx;
        seg[k] = val;
        while (k > 1) {
            k >>= 1;
            seg[k] = seg[2*k] + seg[2*k+1];
        }
    }

    ll prod(int l, int r) { // [l, r)
        if (l >= r) return 0;
        l += size_; r += size_;
        ll resl = e, resr = e;
        while (l < r) {
            if (l & 1) resl = resl + seg[l++];
            if (r & 1) resr = seg[--r] + resr;
            l >>= 1; r >>= 1;
        }
        return resl + resr;
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, m;
    if (!(cin >> n >> m)) return 0;
    vector<ll> rate(m, 0);
    vector<pair<int,int>> each_range(m, {0,0});
    vector<int> pos(n, 0);
    const ll ID = 0;

    vector<Node> init(m);
    for (int i = 0; i < m; ++i) init[i] = Node(0, 1);
    LazySegTree lst;
    lst.build(init);

    for (int i = 0; i < n; ++i) {
        int a, l, r;
        cin >> a >> l >> r;
        rate[i] = a;
        pos[i] = i;
        each_range[i] = {l, r};
        lst.range_apply(l - 1, r, 1);
    }

    SegTree st;
    st.build(rate);

    ll crr_ans = 0;
    for (int i = 0; i < m; ++i) {
        if (rate[i] == 0) continue;
        int l = each_range[i].first;
        int r = each_range[i].second;
        ll len = (ll)(r - l + 1);
        ll s = st.prod(l - 1, r);
        crr_ans += rate[i] * len - s;
    }

    int q;
    cin >> q;
    vector<ll> answers;
    answers.reserve(q);
    for (int qi = 0; qi < q; ++qi) {
        int x, y, u, v;
        cin >> x >> y >> u >> v;
        --x; --y;
        int px = pos[x];
        int l = each_range[px].first;
        int r = each_range[px].second;
        ll minus = lst.get(px).sum;
        if (l - 1 <= px && px < r) minus -= 1;
        crr_ans += rate[px] * minus;
        lst.range_apply(l - 1, r, -1);

        crr_ans -= rate[px] * (ll)(r - l + 1) - st.prod(l - 1, r);

        rate[y] = rate[px];
        rate[px] = 0;
        st.set(px, 0);
        st.set(y, rate[y]);
        each_range[px] = {0, 0};
        each_range[y] = {u, v};

        crr_ans -= rate[y] * lst.get(y).sum;
        lst.range_apply(u - 1, v, 1);

        crr_ans += rate[y] * (ll)(v - u + 1) - st.prod(u - 1, v);

        pos[x] = y;
        answers.push_back(crr_ans);
    }

    for (size_t i = 0; i < answers.size(); ++i) {
        cout << answers[i] << '\n';
    }
    return 0;
}
0