考虑一段区间如果颜色相同就可以合并。记录三个变量,颜色,增量,总和。颜色为正数时表示该段区间全为改颜色,为0时表示该段区间至少有一个颜色不同。。。更新时一定要更新到颜色不为0的节点,否则就向下更新。。。
#include <iostream> #include <sstream> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <climits> #define maxn 100005 #define eps 1e-6 #define mod 20090717 #define INF 99999999 #define lowbit(x) (x&(-x)) #define lson o<<1, L, mid #define rson o<<1 | 1, mid+1, R typedef long long LL; typedef unsigned long long ULL; using namespace std; LL color[maxn<<2]; LL sum[maxn<<2]; LL delta[maxn<<2]; int n, m, ql, qr, x; LL ans; void build(int o, int L, int R) { if(L==R) { sum[o] = delta[o] = 0; color[o] = L; return; } color[o] = 0; int mid = (L+R)>>1; build(lson); build(rson); } void pushup(int o, int L, int R) { if(color[o<<1] == color[o<<1 | 1]) color[o] = color[o<<1]; else color[o] = 0; sum[o] = sum[o<<1] + sum[o<<1 | 1]; } void pushdown(int o, int L, int R) { if(!color[o]) return; int mid = (R+L)>>1; delta[o<<1] += delta[o]; delta[o<<1 | 1] += delta[o]; sum[o<<1] += delta[o]*(mid - L + 1); sum[o<<1 | 1] += delta[o]*(R - mid); color[o<<1] = color[o<<1 | 1] = color[o]; delta[o] = color[o] = 0; } void updata(int o, int L, int R) { if(ql <= L && qr >= R && color[o]) { delta[o] += abs(color[o] - x); sum[o] += abs(color[o] - x)*(R-L+1); color[o] = x; return; } pushdown(o, L, R); int mid = (L+R)>>1; if(ql<=mid) updata(lson); if(qr>mid) updata(rson); pushup(o, L, R); } void query(int o, int L, int R) { if(ql <= L && qr >= R){ ans += sum[o]; return; } pushdown(o, L, R); int mid = (L+R)>>1; if(ql<=mid) query(lson); if(qr>mid) query(rson); pushup(o, L, R); } void debug(void) { printf("%I64d %I64d\n", sum[4], sum[5]); } void solve(void) { int k; while(m--) { scanf("%d", &k); if(k == 1) { scanf("%d%d%d", &ql, &qr, &x); updata(1, 1, n); } else { scanf("%d%d", &ql, &qr); ans = 0; query(1, 1, n); printf("%I64d\n", ans); } } } int main(void) { scanf("%d%d", &n, &m); build(1, 1, n); solve(); return 0; }