题目链接:Minimum
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<vector>
#include<cmath>
#include<map>
#include<set>
#include<cstdlib>
#define mem(a,b) memset(a,b,sizeof(a))
#define INF 0x7fffffff
typedef long long ll;
using namespace std;
const int maxn = (1 << 17) + 10;
const int maxNode = maxn << 2;
int MAX[maxNode];
int MIN[maxNode];
void pushUpMax(int rt){
MAX[rt] = max(MAX[rt<<1],MAX[rt<<1|1]);
}
void pushUpMin(int rt){
MIN[rt] = min(MIN[rt<<1],MIN[rt<<1|1]);
}
void build(int rt,int l,int r){
if(l == r){
scanf("%d",&MAX[rt]);
MIN[rt] = MAX[rt];
return;
}
int mid = (l+r)/2;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
pushUpMax(rt);
pushUpMin(rt);
}
int queryMin(int rt,int l,int r,int L,int R){
if(l <= L && R <= r){
return MIN[rt];
}
int mid = (L+R)/2;
int ans = maxn;
if(l <= mid) ans = min(ans,queryMin(rt<<1,l,r,L,mid));
if(r > mid) ans = min(ans,queryMin(rt<<1|1,l,r,mid+1,R));
return ans;
}
int queryMax(int rt,int l,int r,int L,int R){
if(l <= L && R <= r){
return MAX[rt];
}
int mid = (L+R)/2;
int ans = -maxn;
if(l <= mid){
ans = max(ans,queryMax(rt<<1,l,r,L,mid));
}
if(r > mid){
ans = max(ans,queryMax(rt<<1|1,l,r,mid+1,R));
}
return ans;
}
void update(int rt,int pos,int val,int L,int R){
if(L == R){
MAX[rt] = MIN[rt] = val;
return;
}
int mid = (L+R)/2;
if(pos <= mid) update(rt<<1,pos,val,L,mid);
else update(rt<<1|1,pos,val,mid+1,R);
pushUpMax(rt);
pushUpMin(rt);
}
int main(){
int T,n,m;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
n = (1 << n);
build(1,1,n);
scanf("%d",&m);
while(m--){
int a,b,ch;
scanf("%d%d%d",&ch,&a,&b);
if(ch == 1){
ll ans;
int minn = queryMin(1,a+1,b+1,1,n);
int maxx = queryMax(1,a+1,b+1,1,n);
if(minn == 0 || maxx == 0) puts("0");
else if(minn > 0){
ans = (ll)minn * minn;
}else if(maxx < 0){
ans = (ll)maxx * maxx;
}else{
ans = (ll)maxx * minn;
}
printf("%lld\n",ans);
}else{
update(1,a+1,b,1,n);
}
}
}
return 0;
}