• UVA 11992 ——线段树(区间修改)


    解题思路:

      将矩阵每一行建立一棵线段树,进而变成一维问题求解。注意数组要开 4*N

    代码如下:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 
      6 using namespace std;
      7 const int maxn = 1000000 + 10;
      8 
      9 const int INF = 2000000000;
     10 int q, x1_, x2_, y1, y2, v_add, v_set;
     11 
     12 struct segment_tree {
     13     int sumv[4*maxn],minv[4*maxn],maxv[4*maxn];
     14     int addv[4*maxn], setv[4*maxn];
     15     void maintain(int o, int L, int R) {
     16         int lc = 2*o, rc = 2*o + 1;
     17         sumv[o] = minv[o] = maxv[o] = 0;
     18         if(setv[o] >= 0) {
     19             sumv[o] = setv[o] * (R-L+1);
     20             minv[o] = maxv[o] = setv[o];
     21         }
     22         else if(R > L) {
     23             sumv[o] = sumv[lc] + sumv[rc];
     24             minv[o] = min(minv[lc], minv[rc]);
     25             maxv[o] = max(maxv[lc], maxv[rc]);
     26         }
     27         minv[o] += addv[o]; maxv[o] += addv[o]; sumv[o] += addv[o] * (R-L+1);
     28     }
     29     void pushdown(int o) {
     30         int lc = 2*o, rc = 2*o+1;
     31         if(setv[o] >= 0) {
     32             setv[lc] = setv[rc] = setv[o];
     33             addv[lc] = addv[rc] = 0;
     34             setv[o] = -1;
     35         }
     36         if(addv[o] > 0) {
     37             addv[lc] += addv[o];
     38             addv[rc] += addv[o];
     39             addv[o] = 0;
     40         }
     41     }
     42     void update_add(int o, int L, int R) {
     43         int lc = 2*o, rc = o*2+1;
     44         if(y1 <= L && y2 >= R) {
     45             addv[o] += v_add;
     46         }
     47         else {
     48             pushdown(o);
     49             int M = L + (R-L)/2;
     50             if(y1 <= M) update_add(lc, L, M); else maintain(lc, L, M);
     51             if(y2 > M) update_add(rc, M+1, R);else maintain(rc, M+1, R);
     52         }
     53         maintain(o, L, R);
     54     }
     55     void update_set(int o, int L, int R) {
     56         int lc = 2*o, rc = o*2+1;
     57         if(y1 <= L && y2 >= R) {
     58             setv[o] = v_set;
     59             addv[o] = 0;
     60         }
     61         else {
     62             pushdown(o);
     63             int M = L + (R-L)/2;
     64             if(y1 <= M) update_set(lc, L, M); else maintain(lc, L, M);
     65             if(y2 > M) update_set(rc, M+1, R); else maintain(rc, M+1, R);
     66         }
     67         maintain(o, L, R);
     68     }
     69 
     70     void query(int o, int L, int R, int add, int& _min, int& _max, int& _sum) {
     71         if(setv[o] >= 0) {
     72             _sum += (add+setv[o]+addv[o]) * (min(R, y2)-max(L, y1)+1);
     73             _min = min(_min, setv[o]+addv[o]+add);
     74             _max = max(_max, setv[o]+addv[o]+add);
     75         }
     76         else if(y1 <= L && y2 >= R) {
     77             _sum += sumv[o] + add * (R-L+1);
     78             _min = min(_min, minv[o]+add);
     79             _max = max(_max, maxv[o]+add);
     80         }
     81         else {
     82             int M = L + (R-L)/2;
     83             if(y1 <= M) query(o*2, L, M, add+addv[o], _min, _max, _sum);
     84             if(y2 > M) query(o*2+1, M+1, R, add+addv[o], _min, _max, _sum);
     85         }
     86     }
     87 
     88     void init() {
     89         memset(setv, -1, sizeof setv);
     90         memset(addv, 0, sizeof addv);
     91         memset(sumv, 0, sizeof sumv);
     92         memset(minv, 0, sizeof minv);
     93         memset(maxv, 0, sizeof maxv);
     94     }
     95 };
     96 int r, c, m;
     97 const int maxr = 20 + 5;
     98 
     99 segment_tree tree[maxr];
    100 
    101 int main(int argc, const char * argv[]) {
    102     
    103     while(scanf("%d%d%d", &r, &c, &m) == 3){
    104         
    105         for(int i = 0; i < maxr; i++) tree[i].init();
    106         for(int i = 0; i < m; i++) {
    107             
    108             scanf("%d%d%d%d%d", &q, &x1_, &y1, &x2_, &y2);
    109             if(q == 1){
    110                 scanf("%d", &v_add);
    111                 for(int x = x1_; x <= x2_; x++) {
    112                     tree[x].update_add(1, 1, c);
    113                 }
    114             }
    115             if(q == 2) {
    116                 scanf("%d", &v_set);
    117                 for(int x = x1_; x <= x2_; x++) {
    118                     tree[x].update_set(1, 1, c);
    119                 }
    120             }
    121             if(q == 3){
    122                 int gmin = INF, gmax = -INF, gsum = 0;
    123                 for(int x = x1_; x <= x2_; x++) {
    124                     int _min = INF, _max = -INF, _sum = 0;
    125                     tree[x].query(1, 1, c, 0,_min, _max, _sum);
    126                     gsum += _sum;
    127                     gmin = min(gmin, _min);
    128                     gmax = max(gmax, _max);
    129                 }
    130                 printf("%d %d %d
    ",  gsum, gmin, gmax);
    131             }
    132         }
    133     }
    134     return 0;
    135 }
  • 相关阅读:
    2019-2020信息安全系统设计基础 20175306 20175309 20175326 实验二 固件程序设计
    2019-2020信息安全系统设计基础 20175306 20175309 20175326 实验一 开发环境的熟悉
    2018-2019-2 20175306实验五《网络编程与安全》实验报告
    2018-2019-2 20175306实验四《Android程序设计》实验报告
    20175306王佳烁第十一周学习总结
    20175306王佳烁第十周学习总结
    20165229 NetSec Exp9 Web安全基础
    2018-2019-2 20165229《网络对抗技术》Exp 8 Web基础
    20165229《网络对抗技术》Exp7 网络欺诈防范
    20165229《网络攻防技术》Exp6 信息搜集与漏洞扫描
  • 原文地址:https://www.cnblogs.com/Kiraa/p/6046300.html
Copyright © 2020-2023  润新知