[hdu 4819 Mosaic]二维线段树
分类:Data Structure
SegMent Tree
template
1. 题目链接
2. 题意描述
给定一个
800∗800
的二维矩阵的初始状态,然后
Q(1≤Q≤100000)
次操作,每次查询点
(x,y)
为中心,边长为
l
的领域中的最大值、最小值,然后用
3. 解题思路
单点更新,区间查询的二维线段树裸题。
4. 实现代码
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <ctime>
#include <cmath>
#include <cctype>
#include <cstdio>
#include <string>
#include <cstring>
#include <cassert>
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef long double LB;
typedef unsigned int uint;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef pair<LB, LB> PLB;
typedef vector<int> VI;
const int INF = 0x3f3f3f3f;
const LL INFL = 0x3f3f3f3f3f3f3f3fLL;
const long double PI = acos(-1.0);
const long double eps = 1e-4;
void debug() { cout << endl; }
template<typename T, typename ...R> void debug (T f, R ...r) { cout << "[" << f << "]"; debug (r...); }
template<typename T> inline void umax(T &a, T b) { a = max(a, b); }
template<typename T> inline void umin(T &a, T b) { a = min(a, b); }
template <typename T> inline bool scan_d (T &ret) {
char c; int sgn;
if (c = getchar(), c == EOF) return 0; //EOF
while (c != '-' && (c < '0' || c > '9') ) if((c = getchar()) == EOF) return 0;
sgn = (c == '-') ? -1 : 1;
ret = (c == '-') ? 0 : (c - '0');
while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0');
ret *= sgn;
return 1;
}
template<typename T> void print(T x) {
static char s[33], *s1; s1 = s;
if (!x) *s1++ = '0';
if (x < 0) putchar('-'), x = -x;
while(x) *s1++ = (x % 10 + '0'), x /= 10;
while(s1-- != s) putchar(*s1);
}
template<typename T> void println(T x) { print(x); putchar('\n'); }
template<typename T> T randIntv(T a, T b) { return rand() % (b - a + 1) + a; } /*[a, b]*/
const int MAXN = 805;
LL T, n, Q, N;
LL seg[MAXN << 2][MAXN << 2][2], A[MAXN][MAXN];
#define lch (rt << 1)
#define rch (rt << 1 | 1)
#define lson l, md, (rt << 1)
#define rson md + 1, r, (rt << 1 | 1)
inline void pushUp_sub(int rt, int prt) {
seg[prt][rt][0] = min(seg[prt][lch][0], seg[prt][rch][0]);
seg[prt][rt][1] = max(seg[prt][lch][1], seg[prt][rch][1]);
}
inline void upd(int prt, int rt, int x, int v) {
if(~x) seg[prt][rt][0] = seg[prt][rt][1] = v;
else {
seg[prt][rt][0] = min(seg[prt << 1][rt][0], seg[prt << 1 | 1][rt][0]);
seg[prt][rt][1] = max(seg[prt << 1][rt][1], seg[prt << 1 | 1][rt][1]);
}
}
void build_sub(int l, int r, int rt, int prt, int x) {
if(l == r) {
upd(prt, rt, x, ~x ? A[x][l] : -1);
return;
}
int md = (l + r) >> 1;
build_sub(lson, prt, x);
build_sub(rson, prt, x);
pushUp_sub(rt, prt);
}
void build(int l, int r, int rt) {
if(l == r) {
build_sub(1, N, 1, rt, l);
return;
}
int md = (l + r) >> 1;
build(lson);
build(rson);
build_sub(1, n, 1, rt, -1);
}
void update_sub(int Y, int val, int l, int r, int rt, int prt, int x) {
if(l == r) {
upd(prt, rt, x, val);
return;
}
int md = (l + r) >> 1;
if(Y <= md) update_sub(Y, val, lson, prt, x);
else update_sub(Y, val, rson, prt, x);
pushUp_sub(rt, prt);
}
void update(int X, int Y, int val, int l, int r, int rt) {
if(l == r) {
update_sub(Y, val, 1, N, 1, rt, l);
return;
}
int md = (l + r) >> 1;
if(X <= md) update(X, Y, val, lson);
else update(X, Y, val, rson);
update_sub(Y, -1, 1, n, 1, rt, -1);
}
PLL query_sub(int LY, int RY, int l, int r, int rt, int prt, int pl, int pr) {
if(LY <= l && r <= RY) return make_pair(seg[prt][rt][0], seg[prt][rt][1]);
int md = (l + r) >> 1; PLL lop(INFL, 0), rop(INFL, 0);
if(LY <= md) lop = query_sub(LY, RY, lson, prt, pl, pr);
if(RY > md) rop = query_sub(LY, RY, rson, prt, pl, pr);
return make_pair(min(lop.first, rop.first), max(lop.second, rop.second));
}
PLL query(int LX, int RX, int LY, int RY, int l, int r, int rt) {
if(LX <= l && r <= RX) return query_sub(LY, RY, 1, N, 1, rt, l, r);
int md = (l + r) >> 1; PLL lop(INFL, 0), rop(INFL, 0);
if(LX <= md) lop = query(LX, RX, LY, RY, lson);
if(RX > md) rop = query(LX, RX, LY, RY, rson);
return make_pair(min(lop.first, rop.first), max(lop.second, rop.second));
}
int main() {
#ifdef ___LOCAL_WONZY___
freopen ("input.txt", "r", stdin);
#endif // ___LOCAL_WONZY___
LL x, y, l, v; int cas = 0;
scan_d(T);
while(T --) {
scan_d(n); N = n;
build(1, N, 1);
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= n; ++j) {
scan_d(v);
update(i, j, v, 1, N, 1);
}
}
printf("Case #%d:\n", ++ cas);
scan_d(Q);
while(Q --) {
scan_d(x), scan_d(y), scan_d(l);
LL lx = x - (l >> 1); LL rx = x + (l >> 1);
LL ly = y - (l >> 1); LL ry = y + (l >> 1);
umax(lx, 1LL), umin(rx, N);
umax(ly, 1LL), umin(ry, N);
PLL ret = query(lx, rx, ly, ry, 1, N, 1);
v = (ret.first + ret.second) >> 1;
update(x, y, v, 1, N, 1);
println(v);
}
}
#ifdef ___LOCAL_WONZY___
cout << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC * 1000 << " ms." << endl;
#endif // ___LOCAL_WONZY___
return 0;
}