思路:很明显要用二维线段树,这应该是二维线段树里的入门题。。。。。今天我也是第一次打,如果对一维线段树具有比较深刻的了解,只要稍微想想,画画图,大概就知道怎么写了,只不过代码比较多,找错要找半天。。。我手残l写成了1,还写错两次找了我半天,醉。。。下面给代码。
#include<iostream> #include<stack> #include<cstring> #include<map> #include<string> #include<queue> #include<algorithm> #include<cstdio> #include<set> #include<cmath> using namespace std; #define maxn 805<<2 #define ll (now<<1) #define rr (now<<1|1) #define inf 0x3f3f3f3f typedef long long LL; int maxnum[maxn][maxn], minnum[maxn][maxn]; int n, index, jud, x, y, value, la, ra, lb, rb; void buildson(int l, int r, int now){ if (l == r){ if (jud){ scanf("%d", &maxnum[index][now]); minnum[index][now] = maxnum[index][now]; } else{ maxnum[index][now] = max(maxnum[index << 1][now], maxnum[index << 1 | 1][now]); minnum[index][now] = min(minnum[index << 1][now], minnum[index << 1 | 1][now]); } return; } int mid = (l + r) >> 1; buildson(l, mid, ll); buildson(mid + 1, r, rr); maxnum[index][now] = max(maxnum[index][ll], maxnum[index][rr]); minnum[index][now] = min(minnum[index][ll], minnum[index][rr]); } void build(int l, int r, int now){ if (l == r){ jud = true; index = now; buildson(1, n, 1); jud = false; return; } int mid = (l + r) >> 1; build(l, mid, ll); build(mid + 1, r, rr); index = now; buildson(1, n, 1); } void updateson(int l, int r, int now){ if (l == r){ if (jud){ minnum[index][now] = value; maxnum[index][now] = value; } else{ maxnum[index][now] = max(maxnum[index << 1][now], maxnum[index << 1 | 1][now]); minnum[index][now] = min(minnum[index << 1][now], minnum[index << 1 | 1][now]); } return; } int mid = (l + r) >> 1; if (y <= mid) updateson(l, mid, ll); else updateson(mid + 1, r, rr); maxnum[index][now] = max(maxnum[index][ll], maxnum[index][rr]); minnum[index][now] = min(minnum[index][ll], minnum[index][rr]); } void update(int l, int r, int now){ if (l == r){ jud = true; index = now; updateson(1, n, 1); jud = false; return; } int mid = (l + r) >> 1; if (x <= mid) update(l, mid, ll); else update(mid + 1, r, rr); index = now; updateson(1, n, 1); } int querymaxson(int l, int r, int now){ if (lb <= l&&rb >= r){ return maxnum[index][now]; } int mid = (l + r) >> 1; int a = 0, b = 0; if (lb <= mid) a = querymaxson(l, mid, ll); if (rb > mid) b = querymaxson(mid + 1, r, rr); return max(a, b); } int querymax(int l, int r, int now){ if (la <= l&&ra >= r){ index = now; return querymaxson(1, n, 1); } int mid = (l + r) >> 1; int a = 0, b = 0; if (la <= mid) a = querymax(l, mid, ll); if (ra > mid) b = querymax(mid + 1, r, rr); return max(a, b); } int queryminson(int l, int r, int now){ if (lb <= l&&rb >= r){ return minnum[index][now]; } int mid = (l + r) >> 1; int a = inf, b = inf; if (lb <= mid) a = queryminson(l, mid, ll); if (rb > mid) b = queryminson(mid + 1, r, rr); return min(a, b); } int querymin(int l, int r, int now){ if (la <= l&&ra >= r){ index = now; return queryminson(1, n, 1); } int mid = (l + r) >> 1; int a = inf, b = inf; if (la <= mid) a = querymin(l, mid, ll); if (ra > mid) b = querymin(mid + 1, r, rr); return min(a, b); } int main(){ int t; scanf("%d", &t); for (int tcase = 1; tcase <= t; tcase++){ scanf("%d", &n); build(1, n, 1); int q; scanf("%d", &q); printf("Case #%d:\n", tcase); while (q--){ int len; scanf("%d%d%d", &x, &y, &len); la = max(1, x - (len >> 1)); ra = min(n, x + (len >> 1)); lb = max(1, y - (len >> 1)); rb = min(n, y + (len >> 1)); int a = querymax(1, n, 1); int b = querymin(1, n, 1); value = (a + b) >> 1; printf("%d\n", value); update(1, n, 1); } } }