题目链接:https://hihocoder.com/contest/acmicpc2017beijingonline/problem/9
简单线段树,注意两种flag,数可正可负,弄清思路,就OK了。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#define lson step<<1
#define rson step<<1|1
#define MID (l+r)>>1
#define INF 0x3f3f3f3f
#define maxn 1000001//注意数组的大小
#define LL long long
using namespace std;
int treemx[maxn<<2];
int treemi[maxn<<2];
void pushup(int step)
{
treemi[step]=min(treemi[lson],treemi[rson]);
treemx[step]=max(treemx[lson],treemx[rson]);
}
void build(int l,int r,int step)
{
if(l==r)
{
int t;
scanf("%d",&t);
treemi[step]=treemx[step]=t;
return ;
}
int mid=MID;
build(l,mid,lson);
build(mid+1,r,rson);
pushup(step);
}
void update(int l,int r,int pos,int value,int step)
{
if(l==r)
{
treemx[step]=value;
treemi[step]=value;
return ;
}
int mid=MID;
if(pos<=mid)
update(l,mid,pos,value,lson);
else
update(mid+1,r,pos,value,rson);
pushup(step);
}
int query(int l,int r,int left,int right,int step,int flag)
{
if(l==left&&r==right)
{
if(flag)
return treemx[step];
else
return treemi[step];
}
int mid=MID;;
if(right<=mid)
return query(l,mid,left,right,lson,flag);
else if(left>mid)
return query(mid+1,r,left,right,rson,flag);
else
{
if(flag)
return max(query(l,mid,left,mid,lson,flag),query(mid+1,r,mid+1,right,rson,flag));
else
return min(query(l,mid,left,mid,lson,flag),query(mid+1,r,mid+1,right,rson,flag));
}
}
LL fixed(LL mx,LL mi)
{
if(mi<=0&&mx<=0)
return mx*mx;
if(mi<=0&&mx>=0)
return mi*mx;
if(mi>=0&&mx>=0)
return mi*mi;
}
int main()
{
int T,k,q;
scanf("%d",&T);
while(T--)
{
scanf("%d",&k);
k=pow(2,k);
build(1,k,1);
scanf("%d",&q);
for(int i=0;i<q;i++)
{
int bz,a,b;
scanf("%d %d %d",&bz,&a,&b);
if(bz==2)
update(1,k,a+1,b,1);
else if(bz==1)
{
LL ans,mx,mi;//注意结果大小,应该定义long long,卡了好久
mx=query(1,k,a+1,b+1,1,1);
mi=query(1,k,a+1,b+1,1,0);
ans=fixed(mx,mi);
printf("%lld\n",ans);
}
}
}
return 0;
}