UOJ164 线段树历史最值查询
来源:互联网 发布:行业的选择 知乎 编辑:程序博客网 时间:2024/05/16 19:40
对于线段树的历史查询我们可以用一个二元组
定义(a, b)表示+a对b取max
我们用二元组(a, b), (c, d)分别表示当前以及历史的标记;
注意顺序的问题很重要,提醒一下重载运算符会很方便,还要注意负无穷相加得太多会爆,合并时对标记-oo取max很有必要,好像很抽象,那我在代码里注释一下,防止大家被坑。。。。
#include <cstring>#include <cstdio>typedef long long LL;const LL oo = 1LL << 60;const int MXN = 2e6 + 10;#define rep(i, s, t) for(int i = s; i <= t; ++i)template<class T>T max(T x, T y) {return x>y?x:y;}template<class T>T read(T x = 0, T f = 1) { char c = getchar(); while(c < '0' || c > '9') f = c=='-'?-1:1, c = getchar(); while(c >= '0' && c <= '9') x = x*10 + c-'0', c = getchar(); return x * f;}int n, m;namespace Segment_Tree { struct Tag { LL a, b; Tag() {a = 0; b = -oo;} LL big() {return max(a, b);} void CLR() {a = 0; b = -oo;} Tag link(LL _a, LL _b) {a = _a, b = _b; return *this;} }T[MXN], G, H[MXN]; Tag operator + (Tag p, Tag s) { Tag New; return New.link(max(s.a+p.a, -oo), max(s.b+p.a, p.b)); //notice :: max(~, -oo)!!!!! } Tag operator ^ (Tag p, Tag s) { Tag New; return New.link(max(p.a, s.a), max(p.b, s.b)); }#define l(h) h<<1#define r(h) h<<1|1 void push_down(int h) { H[l(h)] = (H[h] + T[l(h)]) ^ H[l(h)]; H[r(h)] = (H[h] + T[r(h)]) ^ H[r(h)]; T[l(h)] = T[h] + T[l(h)]; T[r(h)] = T[h] + T[r(h)]; T[h].CLR(); H[h].CLR(); }/*(x, -oo)(-x, 0)(-oo, x)*/ void build(int h, int L, int R) { if(L == R) { H[h] = T[h].link(read<LL>(), -oo); return ; } int M = (L + R) >> 1; build(l(h), L, M); build(r(h), M+1, R); } void update(int h, int L, int R, int u, int v) { if(u <= L && R <= v) { T[h] = G + T[h]; H[h] = H[h] ^ T[h]; }else { push_down(h); int M = (L + R) >> 1; if(u <= M) update(l(h), L, M, u, v); if(v > M) update(r(h), M+1, R, u, v); } } LL query(int h, int L, int R, int u, bool f) { if(L == R) return f? T[h].big() : H[h].big(); push_down(h); int M = (L + R) >> 1; if(u <= M) return query(l(h), L, M, u, f); else return query(r(h), M+1, R, u, f); }};using namespace Segment_Tree;void input() { n = read<int>(), m = read<int>(); build(1, 1, n);}void output() { rep(i, 1, m) { int type = read<int>(); if(type <= 3) { int u = read<int>(), v = read<int>(); LL x = read<LL>(); if(type == 1) G.link(x, -oo); else if(type == 2) G.link(-x, 0); else if(type == 3) G.link(-oo, x); update(1, 1, n, u, v); }else { int u = read<int>(); LL Ans = query(1, 1, n, u, type==4); printf("%lld\n", Ans); } }}int main() {#ifndef ONLINE_JUDGE freopen("input.in", "r", stdin); freopen("res.out", "w", stdout);#endif input(); output(); return 0;}
0 0
- UOJ164 线段树历史最值查询
- UOJ164 V 线段树lazytag维护历史最值
- [UOJ164] V 记录历史最值线段树
- UOJ164 V 线段树历史查询
- UOJ164--历史最值维护
- UOJ 164 线段树历史最值
- [历史最值线段树] UOJ#164. 【清华集训2015】V
- 线段树实现区间最值查询代码
- 线段树基本应用——区间最值查询
- HDU 3264 Balanced Lineup(线段树,最值查询)
- hdu5289 二分 + 区间最值查询(线段树) + 暴力
- NYOJ 1185 最大最小值 (线段树 & 区间最值查询)
- HUD_1745 I Hate It!【线段树】【最值查询修改】
- (一)线段树入门--区间最值查询
- 【模板】线段树区间修改、区间求和、查询最值
- light oj 1082 - Array Queries【线段树】最简单的查询最值
- 线段树-点修改--点查询--最值查询 Hdu 1754I Hate It
- 区间最值线段树
- Linux---CentOS6.5编译安装ffmpeg环境
- YII2的乐观锁和悲观锁
- 'fopen': The variable or function may be unsafe.
- LDAP 与 Zeppelin 连接之一 ----- LDAP 搭建
- jQuery常用方法,事件,属性简介
- UOJ164 线段树历史最值查询
- jzoj 3812 Mooo Moo
- nios ii FIFO读取FPGA数据交互实验1
- 一般图最大匹配
- ffmpeg常用基本命令(转)
- 数据增强相关总结
- CC2591和RFX2401C在zstack中的设置
- Android 的一些提示框与activity 切换
- PHP学习笔记【二】之《数据库抽象层PDO---PDO连接数据库》