DZY Loves Colors

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();

 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\n",query(b,c,1));
95         }
96     }
97 }
View Code

posted on 2014-07-18 13:36  天依蓝  阅读(393)  评论(0编辑  收藏  举报

导航