• Codeforces 444 C. DZY Loves Colors (线段树+剪枝)


    题目链接:http://codeforces.com/contest/444/problem/C

    给定一个长度为n的序列,初始时ai=i,vali=0(1in).有两种操作:

    1. 将区间[L,R]的值改为x,并且当一个数从y改成x时它的权值vali会增加|xy|.
    2. 询问区间[L,R]的权值和.

    n10^5,1x10^6.

    感觉这是一个比较好的考察线段树区间更新的性质。

    当区间的a[i]一样时,区间更新即可,这是剪枝。

    注意,lazy标记存的是增量。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 const int N = 1e5 + 5;
     5 struct SegTree {
     6     LL l, r, Min, Max;
     7     LL val, lazy;
     8 }T[N << 2];
     9 
    10 LL Abs(LL a) {
    11     return a < 0 ? -a : a;
    12 }
    13 
    14 void pushup(int p) {
    15     T[p].Min = min(T[p << 1].Min, T[(p << 1)|1].Min);
    16     T[p].Max = max(T[p << 1].Max, T[(p << 1)|1].Max);
    17     T[p].val = T[p << 1].val + T[(p << 1)|1].val;
    18 }
    19 
    20 void pushdown(int p) {
    21     if(T[p].l == T[p].r) {
    22         return ;
    23     } else if(T[p].lazy) {
    24         T[p << 1].lazy += T[p].lazy;
    25         T[(p << 1)|1].lazy += T[p].lazy;
    26         T[p << 1].val += T[p].lazy*(LL)(T[p << 1].r - T[p << 1].l + 1);
    27         T[(p << 1)|1].val += T[p].lazy*(LL)(T[(p << 1)|1].r - T[(p << 1)|1].l + 1);
    28         T[p << 1].Min = T[p << 1].Max = T[(p << 1)|1].Max = T[(p << 1)|1].Min = T[p].Min;
    29         T[p].lazy = 0;
    30     }
    31 }
    32 
    33 void build(int p, int l, int r) {
    34     int mid = (l + r) >> 1;
    35     T[p].l = l, T[p].r = r, T[p].lazy = 0;
    36     if(l == r) {
    37         T[p].Max = l, T[p].Min = l;
    38         T[p].val = 0;   
    39         return ;
    40     }
    41     build(p << 1, l, mid);
    42     build((p << 1)|1, mid + 1, r);
    43     pushup(p);
    44 }
    45 
    46 void update(int p, int l, int r, LL add) {
    47     int mid = (T[p].l + T[p].r) >> 1;
    48     pushdown(p);
    49     if(l == T[p].l && T[p].r == r && T[p].Min == T[p].Max) {
    50         T[p].val += (LL)Abs(add - T[p].Min)*(LL)(r - l + 1);
    51         T[p].lazy += Abs(add - T[p].Max);
    52         T[p].Max = T[p].Min = add;
    53         return ;
    54     }
    55     if(r <= mid) {
    56         update(p << 1, l, r, add);
    57     } else if(l > mid) {
    58         update((p << 1)|1, l, r, add);
    59     } else {
    60         update(p << 1, l, mid, add);
    61         update((p << 1)|1, mid + 1, r, add);
    62     }
    63     pushup(p);
    64 }
    65 
    66 LL query(int p, int l, int r) {
    67     int mid = (T[p].l + T[p].r) >> 1;
    68     pushdown(p);
    69     if(l == T[p].l && T[p].r == r) {
    70         return T[p].val;
    71     }
    72     if(r <= mid) {
    73         return query(p << 1, l, r);
    74     } else if(l > mid) {
    75         return query((p << 1)|1, l, r);
    76     } else {
    77         return query(p << 1, l, mid) + query((p << 1)|1, mid + 1, r);
    78     }
    79     pushup(p);
    80 }
    81 
    82 int main()
    83 {
    84     int n, m, l, r, c;
    85     LL add;
    86     scanf("%d %d", &n, &m);
    87     build(1, 1, n);
    88     while(m--) {
    89         scanf("%d %d %d", &c, &l, &r);
    90         if(c == 1) {
    91             scanf("%lld", &add);
    92             update(1, l, r, add);
    93         } else {
    94             printf("%lld
    ", query(1, l, r));
    95         }
    96     }
    97     return 0;
    98 }
  • 相关阅读:
    003.Heartbeat MySQL双主复制
    001.常见监控简介
    微服务探索与实践—服务注册与发现
    设计模式之建造者模式
    .NET Core 3.0之深入源码理解Startup的注册及运行
    【译】.NET Core 3.0 Preview 3中关于ASP.NET Core的更新内容
    C#并发编程之异步编程(三)
    设计模式之中介者模式
    设计模式之单例模式
    设计模式之装饰器模式
  • 原文地址:https://www.cnblogs.com/Recoder/p/5906658.html
Copyright © 2020-2023  润新知