考虑一段区间如果颜色相同就可以合并。记录三个变量,颜色,增量,总和。颜色为正数时表示该段区间全为改颜色,为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;
}