首页 > 技术文章 > 区间赋值状态压缩线段树

tooyoungtoosimple 2015-08-24 23:34 原文

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

 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;

 

推荐阅读