【HDU 4819】Mosaic
【题目链接】
【算法】
二维线段树(树套树)
【代码】
#include<bits/stdc++.h> using namespace std; #define MAXN 800 int i,q,n,xa,xb,ya,yb,l,tmp,T,Max,Min,x,y; struct info { int Max,Min; } Tree[MAXN*3][MAXN*3]; template <typename T> inline void read(T &x) { int f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) { if (c == '-') f = -f; } for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0'; x *= f; } template <typename T> inline void write(T x) { if (x < 0) { putchar('-'); x = -x; } if (x > 9) write(x/10); putchar(x%10+'0'); } template <typename T> inline void writeln(T x) { write(x); puts(""); } inline void push_up(int D,int index) { Tree[D][index].Max = max(Tree[D][index<<1].Max,Tree[D][index<<1|1].Max); Tree[D][index].Min = min(Tree[D][index<<1].Min,Tree[D][index<<1|1].Min); } inline void build_y(int D,int index,int l,int r,int opt) { int mid,val; if (l == r) { if (opt == 1) { read(val); Tree[D][index].Max = Tree[D][index].Min = val; } else { Tree[D][index].Max = max(Tree[D<<1][index].Max,Tree[D<<1|1][index].Max); Tree[D][index].Min = min(Tree[D<<1][index].Min,Tree[D<<1|1][index].Min); } return; } mid = (l + r) >> 1; build_y(D,index<<1,l,mid,opt); build_y(D,index<<1|1,mid+1,r,opt); push_up(D,index); } inline void build_x(int index,int l,int r) { int mid; if (l == r) { build_y(index,1,1,n,1); return; } mid = (l + r) >> 1; build_x(index<<1,l,mid); build_x(index<<1|1,mid+1,r); build_y(index,1,1,n,2); } inline void modify_y(int D,int index,int l,int r,int val,int opt) { int mid; if (l == r) { if (opt == 1) Tree[D][index].Max = Tree[D][index].Min = val; else { Tree[D][index].Max = max(Tree[D<<1][index].Max,Tree[D<<1|1][index].Max); Tree[D][index].Min = min(Tree[D<<1][index].Min,Tree[D<<1|1][index].Min); } return; } mid = (l + r) >> 1; if (mid >= y) modify_y(D,index<<1,l,mid,val,opt); else modify_y(D,index<<1|1,mid+1,r,val,opt); push_up(D,index); } inline void modify_x(int index,int l,int r,int val) { int mid; if (l == r) { modify_y(index,1,1,n,val,1); return; } mid = (l + r) >> 1; if (mid >= x) modify_x(index<<1,l,mid,val); else modify_x(index<<1|1,mid+1,r,val); modify_y(index,1,1,n,val,2); } inline int query_min_y(int D,int index,int l,int r,int x,int y) { int mid; if (l == x && r == y) return Tree[D][index].Min; mid = (l + r) >> 1; if (mid >= y) return query_min_y(D,index<<1,l,mid,x,y); else if (mid + 1 <= x) return query_min_y(D,index<<1|1,mid+1,r,x,y); else return min(query_min_y(D,index<<1,l,mid,x,mid),query_min_y(D,index<<1|1,mid+1,r,mid+1,y)); } inline int query_min_x(int index,int l,int r,int x,int y) { int mid; if (l == x && r == y) return query_min_y(index,1,1,n,ya,yb); mid = (l + r) >> 1; if (mid >= y) return query_min_x(index<<1,l,mid,x,y); else if (mid + 1 <= x) return query_min_x(index<<1|1,mid+1,r,x,y); else return min(query_min_x(index<<1,l,mid,x,mid),query_min_x(index<<1|1,mid+1,r,mid+1,y)); } inline int query_max_y(int D,int index,int l,int r,int x,int y) { int mid; if (l == x && r == y) return Tree[D][index].Max; mid = (l + r) >> 1; if (mid >= y) return query_max_y(D,index<<1,l,mid,x,y); else if (mid + 1 <= x) return query_max_y(D,index<<1|1,mid+1,r,x,y); else return max(query_max_y(D,index<<1,l,mid,x,mid),query_max_y(D,index<<1|1,mid+1,r,mid+1,y)); } inline int query_max_x(int index,int l,int r,int x,int y) { int mid; if (l == x && r == y) return query_max_y(index,1,1,n,ya,yb); mid = (l + r) >> 1; if (mid >= y) return query_max_x(index<<1,l,mid,x,y); else if (mid + 1 <= x) return query_max_x(index<<1|1,mid+1,r,x,y); else return max(query_max_x(index<<1,l,mid,x,mid),query_max_x(index<<1|1,mid+1,r,mid+1,y)); } int main() { read(T); for (i = 1; i <= T; i++) { read(n); build_x(1,1,n); read(q); cout<<"Case #"<< i << ':' << endl; while (q--) { read(x); read(y); read(l); xa = max(1,x-l/2); xb = min(n,x+l/2); ya = max(1,y-l/2); yb = min(n,y+l/2); Max = query_max_x(1,1,n,xa,xb); Min = query_min_x(1,1,n,xa,xb); tmp = (Max + Min) / 2; writeln(tmp); modify_x(1,1,n,tmp); } } return 0; }