CF #446C:http://codeforces.com/problemset/problem/444/C
题意:给你n个数,大小从1到n,然后又两种操作,1 a b c表示把区间a b 更新为c,那么每个数与之前的数有一个改变量|c-ai|, 2 a b 表示查询a b 之间的改变量。
题解:正解必然是线段树。但是线段树的lazy还是不会用,以及要维护的东西也不清楚,这道水线段树都不会。一个值 mul维护当前的数,ans表示总的改变量,sum表示改变量。这里只有mul!=0才开始更新,否则pushdown();
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 #include<map> 7 #include<set> 8 using namespace std; 9 const int N=1*1e5+5; 10 int n,m; 11 int a,b,c; 12 long long d,cnt; 13 struct Node{ 14 int l,r; 15 long long ans; 16 long long val,mul; 17 long long sum; 18 inline int mid(){ 19 return (l+r)/2; 20 } 21 inline int len(){ 22 return r-l+1; 23 } 24 }num[N*4]; 25 void pushup(int rt){ 26 if(num[rt<<1].mul==num[rt<<1|1].mul) 27 num[rt].mul=num[rt<<1].mul; 28 num[rt].ans=num[rt<<1].ans+num[rt<<1|1].ans; 29 } 30 void pushdown(int rt){ 31 if(num[rt].mul!=0){ 32 num[rt<<1|1].mul=num[rt<<1].mul=num[rt].mul; 33 num[rt<<1].ans+=num[rt].sum*num[rt<<1].len(); 34 num[rt<<1|1].ans+=num[rt].sum*num[rt<<1|1].len(); 35 num[rt<<1].sum+=num[rt].sum; 36 num[rt<<1|1].sum+=num[rt].sum; 37 num[rt].mul=num[rt].sum=0; 38 } 39 } 40 void build(int l,int r,int rt){ 41 num[rt].l=l; 42 num[rt].r=r; 43 num[rt].mul=num[rt].ans=num[rt].sum=0; 44 if(l==r){ 45 num[rt].mul=++cnt; 46 return; 47 } 48 int mid=(l+r)/2; 49 build(l,mid,rt<<1); 50 build(mid+1,r,rt<<1|1); 51 pushup(rt); 52 } 53 void update(int l,int r,int rt,long long val){ 54 if(num[rt].l==l&&num[rt].r==r&&num[rt].mul){ 55 num[rt].sum+=abs(num[rt].mul-val); 56 num[rt].ans+=abs(num[rt].mul-val)*num[rt].len(); 57 num[rt].mul=val; 58 return; 59 } 60 pushdown(rt); 61 int mid=num[rt].mid(); 62 if(mid>=r)update(l,r,rt<<1,val); 63 else if(mid<l)update(l,r,rt<<1|1,val); 64 else{ 65 update(l,mid,rt<<1,val); 66 update(mid+1,r,rt<<1|1,val); 67 } 68 pushup(rt); 69 } 70 long long query(int l,int r,int rt){ 71 if(num[rt].l==l&num[rt].r==r){ 72 return num[rt].ans; 73 } 74 pushdown(rt); 75 int mid=num[rt].mid(); 76 if(mid>=r)return query(l,r,rt<<1); 77 else if(mid<l)return query(l,r,rt<<1|1); 78 else{ 79 return query(l,mid,rt<<1)+query(mid+1,r,rt<<1|1); 80 } 81 pushup(rt); 82 } 83 int main(){ 84 while(~scanf("%d%d",&n,&m)){ 85 cnt=0; 86 build(1,n,1); 87 for(int i=1;i<=m;i++){ 88 scanf("%d%d%d",&a,&b,&c); 89 if(a==1){ 90 scanf("%I64d",&d); 91 update(b,c,1,d); 92 } 93 else 94 printf("%I64d ",query(b,c,1)); 95 } 96 } 97 }