Matrix Searching 【ZOJ - 2859】【二維線段樹】
阿新 • • 發佈:2018-11-30
題目連結
簡單的二維線段樹求區間最小值問題,還不用修改操作。
#include <iostream> #include <cstdio> #include <cmath> #include <string> #include <cstring> #include <algorithm> #include <limits> #include <vector> #include <stack> #include <queue> #include <set> #include <map> #define lowbit(x) ( x&(-x) ) #define pi 3.141592653589793 #define e 2.718281828459045 using namespace std; typedef unsigned long long ull; typedef long long ll; const int maxN = 305; int N, Q, a[maxN][maxN], tree[maxN<<2][maxN<<2]; void build_In(int rt, int fa, int l, int r, bool flag, int pos) { if(l == r) { if(flag) tree[fa][rt] = a[pos][l]; else tree[fa][rt] = min(tree[fa<<1][rt], tree[fa<<1|1][rt]); return; } int mid = (l + r)>>1; build_In(rt<<1, fa, l, mid, flag, pos); build_In(rt<<1|1, fa, mid+1, r, flag, pos); tree[fa][rt] = min(tree[fa][rt<<1], tree[fa][rt<<1|1]); } void build_Out(int rt, int l, int r) { if(l == r) { build_In(1, rt, 1, N, true, l); return; } int mid = (l + r)>>1; build_Out(rt<<1, l, mid); build_Out(rt<<1|1, mid+1, r); build_In(1, rt, 1, N, false, 0); } int query_In(int rt, int fa, int l, int r, int ql, int qr) { if(ql<=l && qr>=r) return tree[fa][rt]; int mid = (l + r)>>1; if(ql>mid) return query_In(rt<<1|1, fa, mid+1, r, ql, qr); else if(qr<=mid) return query_In(rt<<1, fa, l, mid, ql, qr); else { int ans = query_In(rt<<1|1, fa, mid+1, r, ql, qr); ans = min(ans, query_In(rt<<1, fa, l, mid, ql, qr)); return ans; } } int query_Out(int rt, int l, int r, int qlx, int qly, int qrx, int qry) { if(qlx<=l && qrx>=r) return query_In(1, rt, 1, N, qly, qry); int mid = (l + r)>>1; if(qlx>mid) return query_Out(rt<<1|1, mid+1, r, qlx, qly, qrx, qry); else if(qrx<=mid) return query_Out(rt<<1, l, mid, qlx, qly, qrx, qry); else { int ans = query_Out(rt<<1|1, mid+1, r, qlx, qly, qrx, qry); ans = min(ans, query_Out(rt<<1, l, mid, qlx, qly, qrx, qry)); return ans; } } int main() { int T; scanf("%d", &T); while(T--) { scanf("%d", &N); for(int i=1; i<=N; i++) for(int j=1; j<=N; j++) scanf("%d", &a[i][j]); build_Out(1, 1, N); scanf("%d", &Q); while(Q--) { int lx, ly, rx, ry; scanf("%d%d%d%d", &lx, &ly, &rx, &ry); printf("%d\n", query_Out(1, 1, N, lx, ly, rx, ry)); } } return 0; }