给一个数组,有两种操作
1:求 x,y in [l,r],Min
Ax∗Ay
2:将
Ax
替换值为 v
挺显然的线段树,分别求区间最大和最小值,如果区间最小值是正数,那么直接是这个数的平方。否则就要看看最大值,如果最大值是正数,那么就是最小值乘最大值(因为是负数),否则的话就是最大值的平方(因为出来是正数)。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 800010, maxx = 0x3f3f3f3f, minn = -0x3f3f3f3f;
struct Node {
int f, s;
Node() {}
Node(int ff, int ss): f(ff), s(ss) {}
};
int a[maxn], b[maxn], n, m, x, y, l, r, op;
void _clear(int x, int l, int r) {
b[x] = minn;
a[x] = maxx;
if (l == r) return;
int mid = (l+r)/2;
_clear(x*2, l, mid);
_clear(x*2+1, mid+1, r);
}
void init() {
_clear(1, 1, n);
}
void a_insert(int x, int l, int r, int t, int v) {
if (l == r) {
a[x] = v; return;
}
int mid = (l+r)/2;
if (t <= mid) a_insert(x*2, l, mid, t, v);
else a_insert(x*2+1, mid+1, r, t, v);
a[x] = min(a[x*2], a[x*2+1]);
}
void b_insert(int x, int l, int r, int t, int v) {
if (l == r) {
b[x] = v; return;
}
int mid = (l+r)/2;
if (t <= mid) b_insert(x*2, l, mid, t, v);
else b_insert(x*2+1, mid+1, r, t, v);
b[x] = max(b[x*2], b[x*2+1]);
}
int a_find(int x, int l, int r, int ll, int rr) {
if (l == ll && r == rr) return a[x];
int mid = (l+r)/2;
if (rr <= mid) return a_find(x*2, l, mid, ll, rr);
else if (ll > mid) return a_find(x*2+1, mid+1, r, ll, rr);
else {
int temp = a_find(x*2, l, mid, ll, mid);
temp = min(temp, a_find(x*2+1, mid+1, r, mid+1, rr));
return temp;
}
}
int b_find(int x, int l, int r, int ll, int rr) {
if (l == ll && r == rr) return b[x];
int mid = (l+r)/2;
if (rr <= mid) return b_find(x*2, l, mid, ll, rr);
else if (ll > mid) return b_find(x*2+1, mid+1, r, ll, rr);
else {
int temp = b_find(x*2, l, mid, ll, mid);
temp = max(temp, b_find(x*2+1, mid+1, r, mid+1, rr));
return temp;
}
}
int main() {
freopen("input.txt","r",stdin);
int T;
scanf("%d", &T);
while (T--) {
scanf("%d", &m);
n = 1;
for (int i = 1; i <= m; i++) n *= 2;
init();
for (int i = 1; i <= n; i++) {
scanf("%d", &x);
a_insert(1, 1, n, i, x);
b_insert(1, 1, n, i, x);
}
scanf("%d", &m);
for (int i = 1; i <= m; i++) {
scanf("%d %d %d", &op, &l, &r);
if (op == 1) {
l++; r++;
if (l == r) {
long long ans = b_find(1, 1, n, l, r);
printf("%lld\n", ans*ans);
} else {
long long ans_l = a_find(1, 1, n, l, r);
long long ans_r = b_find(1, 1, n, l, r);
if (ans_l >= 0) printf("%lld\n", ans_l*ans_l);
else {
if (ans_r >= 0) printf("%lld\n", ans_l*ans_r);
else printf("%lld\n", ans_r*ans_r);
}
}
} else {
l++;
a_insert(1, 1, n, l, r);
b_insert(1, 1, n, l, r);
}
}
}
}