zoukankan      html  css  js  c++  java
  • (线段树两个lazy标记需要设定优先级)UVA 11992

    题意:

    一个n*m的矩阵,最多20行,元素总数量不超过1000000,三种操作,子矩阵+v,子矩阵=v,还有查询子矩阵的(最大值,最小值,和)。

    分析:

    显然需要懒惰标记,而且需要两个,一个lazy表示赋值的标记,一个add表示增加的标记。

    而且需要优先级,显然赋值的优先级比增加高。

    因为如果节点上有add,但是这时候lazy的标记push_down下来,显然过去的已经全都作废。

    而如果节点上有lazy,但是这个时候add的标记push_down下来,显然lazy标记依然有效,并且需要加上新的add标记。

    代码:

      1 #include <queue>
      2 #include <string>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <iostream>
      6 #include <algorithm>
      7 #include <map>
      8 #include <cmath>
      9 
     10 
     11 using namespace  std;
     12 
     13 typedef long long ll;
     14 typedef unsigned long long ull;
     15 typedef pair<int, int> pii;
     16 typedef pair<ull, ull> puu;
     17 
     18 #define inf (0x3f3f3f3f)
     19 #define lnf (0x3f3f3f3f3f3f3f3f)
     20 #define eps (1e-8)
     21 #define fi first
     22 #define se second
     23 
     24 //--------------------------
     25 
     26 const ll mod = 1000000007;
     27 const int maxn = 1000010;
     28 
     29 struct Node {
     30     int left, right;
     31     int sum;
     32     int maxs, mins;
     33     int lazy;
     34     int add;
     35 } node[maxn << 2];
     36 int n, m, q;
     37 
     38 void build(int n, int left, int right) {
     39     node[n].left = left;
     40     node[n].right = right;
     41     node[n].sum = node[n].maxs = node[n].mins = 0;
     42     node[n].lazy  = -1;
     43     node[n].add = 0;
     44     if(left == right)return ;
     45     int mid = (left + right) >> 1;
     46     build(n << 1, left, mid);
     47     build(n << 1 | 1, mid + 1, right);
     48 }
     49 
     50 void push_up(int n) {
     51     node[n].sum = node[n << 1].sum + node[n << 1 | 1].sum;
     52     node[n].mins = min(node[n << 1].mins, node[n << 1 | 1].mins);
     53     node[n].maxs = max(node[n << 1].maxs, node[n << 1 | 1].maxs);
     54 }
     55 
     56 void push_down(int n) {
     57     if(node[n].lazy != -1) {
     58         node[n << 1].lazy = node[n << 1 | 1].lazy = node[n].lazy;
     59         node[n << 1].add = node[n << 1 | 1].add = 0;
     60         node[n << 1].sum = node[n].lazy * (node[n << 1].right - node[n << 1].left + 1);
     61         node[n << 1 | 1].sum = node[n].lazy * (node[n << 1 | 1].right - node[n << 1 | 1].left + 1);
     62         node[n << 1].mins = node[n << 1].maxs = node[n].lazy;
     63         node[n << 1 | 1].mins = node[n << 1 | 1].maxs = node[n].lazy;
     64         node[n].lazy = -1;
     65     }
     66     if(node[n].add != 0) {
     67         node[n << 1].add += node[n].add;
     68         node[n << 1 | 1].add += node[n].add;
     69         node[n << 1].sum += node[n].add * (node[n << 1].right - node[n << 1].left + 1);
     70         node[n << 1 | 1].sum += node[n].add * (node[n << 1 | 1].right - node[n << 1 | 1].left + 1);
     71         node[n << 1].maxs += node[n].add;
     72         node[n << 1].mins += node[n].add;
     73         node[n << 1 | 1].maxs += node[n].add;
     74         node[n << 1 | 1].mins += node[n].add;
     75         node[n].add = 0;
     76     }
     77 }
     78 
     79 void Set(int n, int left, int right, int val) {
     80     if(node[n].left >= left && node[n].right <= right) {
     81         node[n].lazy = val;
     82         node[n].sum = val * (node[n].right - node[n].left + 1);
     83         node[n].mins = val;
     84         node[n].maxs = val;
     85         node[n].add = 0;
     86         return ;
     87     }
     88     push_down(n);
     89     int mid = (node[n].left + node[n].right) >> 1;
     90     if(mid >= left)Set(n << 1, left, right, val);
     91     if(mid < right)Set(n << 1 | 1, left, right, val);
     92     push_up(n);
     93 }
     94 
     95 void Add(int n, int left, int right, int val) {
     96     if(node[n].left >= left && node[n].right <= right) {
     97         node[n].add += val;
     98         node[n].sum += val * (node[n].right - node[n].left + 1);
     99         node[n].mins += val;
    100         node[n].maxs += val;
    101         return ;
    102     }
    103     push_down(n);
    104     int mid = (node[n].left + node[n].right) >> 1;
    105     if(mid >= left)Add(n << 1, left, right, val);
    106     if(mid < right)Add(n << 1 | 1, left, right, val);
    107     push_up(n);
    108 
    109 }
    110 
    111 
    112 int query_sum(int n, int left, int right) {
    113     if(node[n].left >= left && node[n].right <= right) {
    114         return node[n].sum;
    115     }
    116     push_down(n);
    117     int mid = (node[n].left + node[n].right) >> 1;
    118     int sum = 0;
    119     if(mid >= left)sum += query_sum(n << 1, left, right);
    120     if(mid < right)sum += query_sum(n << 1 | 1, left, right);
    121     push_up(n);
    122     return sum;
    123 }
    124 int query_max(int n, int left, int right) {
    125     if(node[n].left >= left && node[n].right <= right) {
    126         return node[n].maxs;
    127     }
    128     push_down(n);
    129     int mid = (node[n].left + node[n].right) >> 1;
    130     int res = -inf;
    131     if(mid >= left)res = max(res, query_max(n << 1, left, right));
    132     if(mid < right)res = max(res, query_max(n << 1 | 1, left, right));
    133     push_up(n);
    134     return res;
    135 }
    136 
    137 int query_min(int n, int left, int right) {
    138     if(node[n].left >= left && node[n].right <= right) {
    139         return node[n].mins;
    140     }
    141     push_down(n);
    142     int mid = (node[n].left + node[n].right) >> 1;
    143     int res = inf;
    144     if(mid >= left)res = min(res, query_min(n << 1, left, right));
    145     if(mid < right)res = min(res, query_min(n << 1 | 1, left, right));
    146     push_up(n);
    147     return res;
    148 }
    149 
    150 void solve() {
    151     while(~scanf("%d%d%d", &n, &m, &q)) {
    152         build(1, 1, n * m);
    153         int op, x1, x2, y1, y2, val;
    154         int c = 0;
    155         while(q--) {
    156             scanf("%d%d%d%d%d", &op, &x1, &y1, &x2, &y2);
    157             if(op == 1) {
    158                 scanf("%d", &val);
    159                 for(int i = x1; i <= x2; i++) {
    160                     Add(1, (i - 1)*m + y1, (i - 1)*m + y2, val);
    161                 }
    162             } else if(op == 2) {
    163                 scanf("%d", &val);
    164                 for(int i = x1; i <= x2; i++) {
    165                     Set(1, (i - 1)*m + y1, (i - 1)*m + y2, val);
    166                 }
    167             } else {
    168                 int a = 0, b = inf, c = -inf;
    169                 for(int i = x1; i <= x2; i++) {
    170                     a += query_sum(1, (i - 1) * m + y1, (i - 1) * m + y2);
    171                     b = min(b, query_min(1, (i - 1) * m + y1, (i - 1) * m + y2));
    172                     c = max(c, query_max(1, (i - 1) * m + y1, (i - 1) * m + y2));
    173                 }
    174                 printf("%d %d %d
    ", a, b, c);
    175             }
    176         }
    177     }
    178 
    179 }
    180 
    181 int main() {
    182 #ifndef ONLINE_JUDGE
    183     freopen("1.in", "r", stdin);
    184 //    freopen("1.out", "w", stdout);
    185 #endif
    186     solve();
    187     return 0;
    188 }
  • 相关阅读:
    PCLVisualizer::addSphere 运行报错解决方案
    八叉树 (转载)
    Django 迁移错误 Cannot add foreign key constraint,字段类型自动变成Bigint(20)
    Django之Model字段详解
    FineReport如何连接hadoop,hive,Impala数据库,Kerberos认证
    图片自适应容器的几种方法
    【windows】查看电池使用情况
    【C++】C++复合变量的定义及易错点
    【c++】C++自定义类注意事项
    金字塔池化Spatial Pyramid Pooling
  • 原文地址:https://www.cnblogs.com/tak-fate/p/6965481.html
Copyright © 2011-2022 走看看