• 区间赋值状态压缩线段树


    有一次打比赛见到的,求一段区间内所有值的异或,对整块区间进行赋值,当时比赛时没有将模板调出来,感觉状压线段树可以当模板整理下来,转载注明出处谢谢

     1 /*
     2 _sum是对区间所有元素做或云算的值
     3 */
     4 int _sum, y11, y22, v;
     5 struct IntervalTree {
     6     int sumv[maxnode], setv[maxnode];
     7 
     8     // 维护信息
     9     void maintain(int o, int L, int R) {
    10         int lc = o*2, rc = o*2+1;
    11         if(R > L) sumv[o] = sumv[lc] | sumv[rc];
    12         if(setv[o] >= 0) sumv[o] = setv[o];
    13     }
    14 
    15     // 标记传递
    16     void unmark(int o) {
    17         int lc = o*2, rc = o*2+1;
    18         if(setv[o] >= 0) {
    19             setv[lc] = setv[rc] = setv[o];
    20             setv[o] = -1; // 清除本结点标记
    21         }
    22     }
    23     void update(int o, int L, int R) {
    24         int lc = o*2, rc = o*2+1;
    25         if(y11 <= L && y22 >= R) setv[o] = v;
    26         else 
    27         {
    28             unmark(o);
    29             int M = L + (R-L)/2;
    30             if(y11 <= M) update(lc, L, M); else maintain(lc, L, M);
    31             if(y22 > M) update(rc, M+1, R); else maintain(rc, M+1, R);
    32         }
    33         maintain(o, L, R);
    34     }
    35     void query(int o, int L, int R) {
    36         if(setv[o] >= 0) _sum |= setv[o];
    37         else if(y11 <= L && y22 >= R) _sum |= sumv[o];
    38         else {
    39             int M = L + (R-L)/2;
    40             if(y11 <= M) query(o*2, L, M);
    41             if(y22 > M) query(o*2+1, M+1, R);
    42         }
    43     }
    44 } tree;
  • 相关阅读:
    select + 回调 + 事件循环
    进程间通信
    多进程复习
    concurrent.futures 使用及解析
    多线程复习 Rlock ,Condition,Semaphore
    生成器读取大文件应用
    VS远程调试与附加调试
    Linux后台有个systemd-r进程,占用5355等端口
    linux中 shell编程 判断服务是否运行
    使用Keepalived实现linux高可用集群
  • 原文地址:https://www.cnblogs.com/tooyoungtoosimple/p/4756262.html
Copyright © 2020-2023  润新知