思路:线段树区间更新,区间内的颜色不一样怎么办呢?col[]数组储存区间内颜色是否一样,一样才更新lazy之类的,否则继续往下递归。
# include <bits/stdc++.h>
# define lson l,m,id<<1
# define rson m+1,r,id<<1|1
using namespace std;
typedef long long LL;
const int maxn = 1e5+30;
LL col[maxn<<2], sum[maxn<<2], lazy[maxn<<2];
void build(int l, int r, int id)
{
if(l==r)
{
col[id] = l;
return;
}
int m = l+r>>1;
build(lson);
build(rson);
sum[id] = sum[id<<1] + sum[id<<1|1];
if(col[id<<1] && col[id<<1]==col[id<<1|1]) col[id] = col[id<<1];
else col[id] = 0;
}
void pushdown(int rt, int dis)
{
if(lazy[rt])
{
lazy[rt<<1] += lazy[rt];
lazy[rt<<1|1] += lazy[rt];
col[rt<<1] = col[rt<<1|1] = col[rt];
sum[rt << 1] += lazy[rt]*(dis-(dis>>1));
sum[rt<<1|1] += lazy[rt]*(dis>>1);
lazy[rt] = 0;
}
}
void update(int L, int R, int val, int l, int r, int id)
{
if(L<=l && R>=r && col[id])
{
lazy[id] += abs(col[id]-val);
sum[id] += (LL)llabs(val-col[id])*(r-l+1);
col[id] = val;
return;
}
pushdown(id, r-l+1);
int m = l+r>>1;
if(L <= m) update(L, R, val, lson);
if(R > m) update(L, R, val, rson);
sum[id] = sum[id<<1] + sum[id<<1|1];
if(col[id<<1] && col[id<<1]==col[id<<1|1]) col[id] = col[id<<1];
else col[id] = 0;
}
LL query(int L, int R, int l, int r, int id)
{
if(L<=l && R>=r)
return sum[id];
pushdown(id, r-l+1);
LL ans = 0;
int m = l+r>>1;
if(L <= m) ans += query(L, R, lson);
if(R > m) ans += query(L, R, rson);
return ans;
}
int main()
{
int n, m;
scanf("%d%d",&n,&m);
build(1, n, 1);
while(m--)
{
int op, l, r, x;
scanf("%d%d%d",&op,&l,&r);
if(op == 1)
{
scanf("%d",&x);
update(l,r,x,1,n,1);
}
else
printf("%I64d\n",query(l,r,1,n,1));
}
return 0;
}