Main idea:
Given an interval of $[1,n] $($1\leq10^5 $), the color of each position in the interval is its interval subscript.
Now there are two operations:
1. Dye the range $[l,r] $into $x $color, and the contribution to the range value is|x-c| (c is the color of the original range)
2. Sum of contribution of query interval
Problem solving analysis:
Add one more variable to judge whether the interval color is the same. When updating to the part with the same interval color, launch. At the same time, launch maintains the extra contribution.
#include <bits/stdc++.h> using namespace std; #define Lson rt<<1,l,mid #define Rson rt<<1|1,mid+1,r #define REP(i,s,t) for(int i=s;i<=t;i++) const int N = 1e5+5; int n,m,cnt; typedef long long ll; template<typename T> inline void read(T&x){ x=0;int f=1;char ch=getchar(); while(ch<'0' ||ch>'9'){ if(ch=='-')f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ x=x*10+ch-'0'; ch=getchar(); } x*=f; } struct Seg{ ll val,col,add; #define val(rt) tr[rt].val #define col(rt) tr[rt].col #define add(rt) tr[rt].add }tr[N<<2]; inline void Pushdown(int rt,int len){ if(add(rt)){ add(rt<<1)+=add(rt); add(rt<<1|1)+=add(rt); val(rt<<1)+=(len-(len>>1))*add(rt); val(rt<<1|1)+=(len>>1)*add(rt); col(rt<<1)=col(rt<<1|1)=col(rt); add(rt)=0; } } inline void Pushup(int rt){ val(rt)=val(rt<<1)+val(rt<<1|1); if(col(rt<<1)==col(rt<<1|1))col(rt)=col(rt<<1|1); else col(rt)=0; } void build(int rt,int l,int r){ if(l==r){ col(rt)=l; return; } int mid=l+r>>1; build(Lson);build(Rson); Pushup(rt); } void update(int rt,int l,int r,int L,int R,int c){ if(L<=l && r<=R && col(rt)){ val(rt)+=(r-l+1)*(abs(c-col(rt))); add(rt)+=abs(c-col(rt)); col(rt)=c; return; } Pushdown(rt,r-l+1); int mid=l+r>>1; if(L<=mid)update(Lson,L,R,c); if(R>mid)update(Rson,L,R,c); Pushup(rt); } ll query(int rt,int l,int r,int L,int R){ if(L<=l && r<=R)return val(rt); Pushdown(rt,r-l+1); int mid=l+r>>1; ll ans=0; if(L<=mid)ans+=query(Lson,L,R); if(R>mid)ans+=query(Rson,L,R); return ans; } int main(){ read(n);read(m); build(1,1,n); while(m--){ int op;read(op); if(op==1){ int u,v;ll w;read(u);read(v);read(w); update(1,1,n,u,v,w); }else{ int u,v;read(u);read(v); printf("%lld\n",query(1,1,n,u,v)); } } }