之前遇到线段树+取模的组合,相比那题,这题比较友好,但也难度中等,记录一下。
/*
题目大意:
有长度为n的数组,起始值A[i] = i,sum[i] = 0现给两种操作
1 left right x:
将A[left],A[left + 1].....A[right]都改为x,sum[i] = abs(x - A[i]);
2 left right
统计[left,right]的sum之和
----------------------
一个有初值的长度n的数组,每次区间修改成同一个值,要记录其中数值的变化大小
每次区间查询当前区间之前变化大小的总和。
----------------------
线段树与绝对值的组合
----------------------
n,m-1e5 ---开4倍
修改的值-1e8 ---用ll
----------------------
解析:
一个个单个修改绝对T,区间修改遇到 这个区间数组值不同 时,绝对值有误差
-->加个判断数组f[maxn<<2],判断这个区间是否都是同一值
*/
#include <bits/stdc++.h>
#pragma GCC optimize(2)
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=1e5+7;
const int mod=1e9+7;
int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+ch-'0';
ch=getchar();
}
return x*f;
}
#define ls i<<1
#define rs i<<1|1
#define lson ls,l,mid
#define rson rs,mid+1,r
int n,m,x,y,z;
struct node{
int l,r,len;
ll a,sum,lazy;
bool f;
}t[maxn<<2];
//a[]这个区间的数组数,sum[]这个区间的代价值
//lazy延迟标记,f[]判断这个区间是否为同一数
void pushup(int i){
t[i].sum=t[ls].sum+t[rs].sum;
if(t[ls].f&&t[rs].f&&t[ls].a==t[rs].a){
t[i].f=1;
t[i].a=t[ls].a;
}
else t[i].f=0;
}
//c为修改后的数组值,add为之前的值与c的差的绝对值
void change(int i,ll c,ll add){
t[i].sum+=(ll)t[i].len*add;
t[i].lazy+=add;
t[i].a=c;
}
void pushdown(int i){
if(t[i].lazy){
ll temp=t[i].lazy;
change(ls,t[i].a,temp);
change(rs,t[i].a,temp);
t[i].lazy=0;
}
}
void build(int i,int l,int r) {
t[i].l=l; t[i].r=r; t[i].len=r-l+1;
t[i].sum=t[i].lazy=t[i].a=t[i].f=0; //可省略
if(l==r){
t[i].f=1; t[i].a=l;
return;
}
int mid=l+r>>1;
build(lson); build(rson);
pushup(i);
}
void update(int i,int l,int r,ll c){
if(t[i].l>r||t[i].r<l) return;
if(l<=t[i].l&&t[i].r<=r&&t[i].f){
change(i,c,abs(t[i].a-c));
return;
}
pushdown(i);
update(ls,l,r,c); update(rs,l,r,c);
pushup(i);
}
ll query(int i,int l,int r){
if(t[i].l>r||t[i].r<l) return 0;
if(l<=t[i].l&&t[i].r<=r) return t[i].sum;
pushdown(i);
return query(ls,l,r)+query(rs,l,r);
}
int main(){
n=read(); m=read();
build(1,1,n);
while(m--){
x=read();
if(x==1){
x=read(); y=read(); z=read();
update(1,x,y,z);
}
else{
x=read(); y=read();
printf("%lld\n",query(1,x,y));
}
}
}
/*
样例一
3 3
1 1 2 4
1 2 3 5
2 1 3
8
样例二
3 4
1 1 3 4
2 1 1
2 2 2
2 3 3
3
2
1
样例三
10 6
1 1 5 3
1 2 7 9
1 10 10 11
1 3 8 12
1 1 10 3
2 1 10
129
*/