给一个n*n的方格, 每个方格有值。 每次询问, 给出三个数x, y, l, 求出以x, y为中心的边长为l的正方形内的最大值与最小值, 输出(maxx+minn)/2, 并将x, y这个格子的值改为(maxx+minn)/2。题目保证l为奇数。
二维线段树的单点更新, 区间查询。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define pb(x) push_back(x) 4 #define ll long long 5 #define mk(x, y) make_pair(x, y) 6 #define lson l, m, rt<<1 7 #define mem(a) memset(a, 0, sizeof(a)) 8 #define rson m+1, r, rt<<1|1 9 #define mem1(a) memset(a, -1, sizeof(a)) 10 #define mem2(a) memset(a, 0x3f, sizeof(a)) 11 #define rep(i, a, n) for(int i = a; i<n; i++) 12 #define ull unsigned long long 13 typedef pair<int, int> pll; 14 const double PI = acos(-1.0); 15 const double eps = 1e-8; 16 const int mod = 1e9+7; 17 const int inf = 1061109567; 18 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; 19 const int maxn = 805; 20 int maxx[maxn<<2][maxn<<2], minn[maxn<<2][maxn<<2], max_ans, min_ans, n; 21 void pushUp(int pos, int rt) { 22 maxx[pos][rt] = max(maxx[pos][rt<<1], maxx[pos][rt<<1|1]); 23 minn[pos][rt] = min(minn[pos][rt<<1], minn[pos][rt<<1|1]); 24 } 25 void sub_build(int sign, int pos, int l, int r, int rt) { 26 if(l == r) { 27 if(!sign) { 28 scanf("%d", &maxx[pos][rt]); 29 minn[pos][rt] = maxx[pos][rt]; 30 } else { 31 minn[pos][rt] = min(minn[pos<<1][rt], minn[pos<<1|1][rt]); 32 maxx[pos][rt] = max(maxx[pos<<1][rt], maxx[pos<<1|1][rt]); 33 } 34 return ; 35 } 36 int m = l+r>>1; 37 sub_build(sign, pos, lson); 38 sub_build(sign, pos, rson); 39 pushUp(pos, rt); 40 } 41 void build(int l, int r, int rt) { 42 if(l == r) { 43 sub_build(0, rt, 1, n, 1); 44 return ; 45 } 46 int m = l+r>>1; 47 build(lson); 48 build(rson); 49 sub_build(1, rt, 1, n, 1); 50 } 51 void sub_update(int sign, int pos, int y, int l, int r, int rt, int val) { 52 if(l == r) { 53 if(!sign) { 54 maxx[pos][rt] = minn[pos][rt] = val; 55 } else { 56 maxx[pos][rt] = max(maxx[pos<<1][rt], maxx[pos<<1|1][rt]); 57 minn[pos][rt] = min(minn[pos<<1][rt], minn[pos<<1|1][rt]); 58 } 59 return ; 60 } 61 int m = l+r>>1; 62 if(y<=m) 63 sub_update(sign, pos, y, lson, val); 64 else 65 sub_update(sign, pos, y, rson, val); 66 pushUp(pos, rt); 67 } 68 void update(int x, int y, int l, int r, int rt, int val) { 69 if(l == r) { 70 sub_update(0, rt, y, 1, n, 1, val); 71 return ; 72 } 73 int m = l+r>>1; 74 if(x<=m) 75 update(x, y, lson, val); 76 else 77 update(x, y, rson, val); 78 sub_update(1, rt, y, 1, n, 1, val); 79 } 80 void sub_query(int pos, int L, int R, int l, int r, int rt) { 81 if(L<=l&&R>=r) { 82 max_ans = max(max_ans, maxx[pos][rt]); 83 min_ans = min(min_ans, minn[pos][rt]); 84 return ; 85 } 86 int m = l+r>>1; 87 if(L<=m) 88 sub_query(pos, L, R, lson); 89 if(R>m) 90 sub_query(pos, L, R, rson); 91 } 92 void query(int LX, int RX, int LY, int RY, int l, int r, int rt) { 93 if(LX<=l&&RX>=r) { 94 sub_query(rt, LY, RY, 1, n, 1); 95 return ; 96 } 97 int m = l+r>>1; 98 if(LX<=m) 99 query(LX, RX, LY, RY, lson); 100 if(RX>m) 101 query(LX, RX, LY, RY, rson); 102 } 103 int main() 104 { 105 int t, x, y, l, q, cnt = 1; 106 cin>>t; 107 while (t--) { 108 scanf("%d", &n); 109 build(1, n, 1); 110 cin>>q; 111 printf("Case #%d: ", cnt++); 112 while(q--) { 113 scanf("%d%d%d", &x, &y, &l); 114 min_ans = inf, max_ans = 0; 115 int LX = max(x-l/2, 1); 116 int RX = min(x+l/2, n); 117 int LY = max(y-l/2, 1); 118 int RY = min(y+l/2, n); 119 query(LX , RX, LY, RY, 1, n, 1); 120 int ans = (min_ans+max_ans)/2; 121 printf("%d ", ans); 122 update(x, y, 1, n, 1, ans); 123 } 124 } 125 }