Files
python/TangDou/AcWing/SegmentTree/CF444C.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

100 lines
2.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <bits/stdc++.h>
using namespace std;
const int N = 500010;
#define int long long
#define mid ((l + r) >> 1)
#define ls (u << 1)
#define rs (u << 1 | 1)
struct Node {
int l, r, len;
int sum; // 属性:权值的和 sum(Wi)
int same; // 属性:区间的颜色值是否相同,如果相同,记录颜色值为same,注意:颜色值从1开始,最大是n
int add; // 懒标记:增加
} tr[N << 2];
void pushup(int u) {
tr[u].sum = tr[ls].sum + tr[rs].sum; // 属性1:Wi权值和
if (tr[ls].same == tr[rs].same) // 属性2:same属性。如果左右儿子的same属性一致,则父亲的same属性标注为左儿子的same属性
tr[u].same = tr[ls].same;
else
tr[u].same = 0;
// 注意:这个else中的same属性也一定要清零!原来是左右儿子一致,再次修改后就不一致,那么父亲需要标记不一致
// 这个和初始值为0没有任何关系,最初我还以为不需要加上这句,后来想想不对,这是一个动态变化的过程,需要及时清零
}
void pushdown(int u) {
if (tr[u].same) { // 如果存在add懒标记,并且整个区间是一样的值
tr[ls].sum += tr[ls].len * tr[u].add;
tr[rs].sum += tr[rs].len * tr[u].add;
tr[ls].add += tr[u].add;
tr[rs].add += tr[u].add;
tr[ls].same = tr[u].same;
tr[rs].same = tr[u].same;
tr[u].add = 0;
}
}
void build(int u, int l, int r) {
tr[u].l = l, tr[u].r = r, tr[u].len = r - l + 1;
if (l == r) {
tr[u].same = l; // 颜色值Ci,初始值为i,对于叶子而言i即是l
return;
}
build(ls, l, mid), build(rs, mid + 1, r);
pushup(u);
}
void modify(int u, int L, int R, int v) {
int l = tr[u].l, r = tr[u].r;
if (l > R || r < L) return;
if (l >= L && r <= R && tr[u].same) {
tr[u].sum += tr[u].len * abs(v - tr[u].same);
tr[u].add += abs(v - tr[u].same);
tr[u].same = v;
return;
}
pushdown(u);
modify(ls, L, R, v), modify(rs, L, R, v);
pushup(u);
}
int query(int u, int L, int R) {
int l = tr[u].l, r = tr[u].r;
if (l >= L && r <= R) return tr[u].sum;
if (l > R || r < L) return 0;
pushdown(u);
return query(ls, L, R) + query(rs, L, R);
}
signed main() {
#ifndef ONLINE_JUDGE
freopen("CF444C.in", "r", stdin);
#endif
// 加快读入
ios::sync_with_stdio(false), cin.tie(0);
int n, m, op;
cin >> n >> m;
// n个元素,构建线段树
build(1, 1, n);
while (m--) {
int op;
cin >> op;
if (op == 1) {
int l, r, x;
cin >> l >> r >> x;
modify(1, l, r, x); // 区间修改为x
} else if (op == 2) {
int l, r;
cin >> l >> r;
cout << query(1, l, r) << endl;
}
}
return 0;
}