描述
You are given a list of integers a0, a1, …, a2^k-1.
You need to support two types of queries:
1. Output Minx,y∈[l,r] {ax∙ay}.
2. Let ax=y.
输入
The first line is an integer T, indicating the number of test cases. (1≤T≤10).
For each test case:
The first line contains an integer k (0 ≤ k ≤ 17).
The following line contains 2k integers, a0, a1, …, a2^k-1 (-2k ≤ ai < 2k).
The next line contains a integer (1 ≤ Q < 2k), indicating the number of queries. Then next Q lines, each line is one of:
1. 1 l r: Output Minx,y∈[l,r]{ax∙ay}. (0 ≤ l ≤ r < 2k)
2. 2 x y: Let ax=y. (0 ≤ x < 2k, -2k≤ y < 2k)
输出
For each query 1, output a line contains an integer, indicating the answer.
1 3 1 1 2 2 1 1 2 2 5 1 0 7 1 1 2 2 1 2 2 2 2 1 1 2样例输出
1 1 4
题意:给一串数字,两种操作,1 x y,查询区间x~y中a[x]*a[y]的最小值,先可以等于y;2 x y,把a[i]改成y;
思路:线段树维护区间最大最小值+单点更新;每次查询区间最小值ans1和最大值ans2;ans1>=0,答案为ans1*ans1;ans1<0时,ans2<0,答案为ans2*ans2,ans2>=0,答案为ans1*ans2;
AC代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<stack>
#define maxn 150000
#define inf 0x7fffffff
using namespace std;
long long n,arr[maxn];
struct node
{
int l;
int r;
long long int mi;
long long int mx;
}segtree[maxn*4];
int tab[20];
void init()
{
tab[0]=1;
for(int i=1;i<=18;i++)
tab[i]=tab[i-1]*2;
}
void pushup(int root)
{
segtree[root].mi=min(segtree[root<<1].mi,segtree[root<<1|1].mi);
segtree[root].mx=max(segtree[root<<1].mx,segtree[root<<1|1].mx);
}
void build(int root,int l,int r)
{
segtree[root].l=l;
segtree[root].r=r;
if(l==r)
{
segtree[root].mi=segtree[root].mx=arr[l];
return;
}
int mid=(l+r)>>1;
build(root<<1,l,mid);
build(root<<1|1,mid+1,r);
pushup(root);
}
long long int query_mi(int root,int l,int r)
{
int ll=segtree[root].l;
int rr=segtree[root].r;
if(l<=ll&&rr<=r)
return segtree[root].mi;
int mid=(ll+rr)>>1;
long long int ans=inf;
if(l<=mid)
ans=min(ans,query_mi(root<<1,l,r));
if(r>mid)
ans=min(ans,query_mi(root<<1|1,l,r));
return ans;
}
long long int query_mx(int root,int l,int r)
{
int ll=segtree[root].l;
int rr=segtree[root].r;
if(l<=ll&&rr<=r)
return segtree[root].mx;
int mid=(ll+rr)>>1;
long long int ans=-inf;
if(l<=mid)
ans=max(ans,query_mx(root<<1,l,r));
if(r>mid)
ans=max(ans,query_mx(root<<1|1,l,r));
return ans;
}
void update(int root,int p,long long int val)
{
int ll=segtree[root].l;
int rr=segtree[root].r;
if(ll==rr)
{
segtree[root].mi=segtree[root].mx=val;
return;
}
int mid=(ll+rr)>>1;
if(p<=mid)
update(root<<1,p,val);
else
update(root<<1|1,p,val);
pushup(root);
}
int main()
{
int t;
init();
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
n=tab[n];
for(int i=1;i<=n;i++)
scanf("%lld",&arr[i]);
build(1,1,n);
int m;
scanf("%d",&m);
while(m--)
{
int op,x;
long long y;
scanf("%d%d%lld",&op,&x,&y);
if(op==1)
{
x++;y++;
long long ans1=query_mi(1,x,y);
long long ans2=query_mx(1,x,y);
//cout<<ans1<<' '<<ans2<<endl;
if(ans1>=0)
printf("%lld\n",ans1*ans1);
else
{
if(ans2>=0)
printf("%lld\n",ans1*ans2);
else
printf("%lld\n",ans2*ans2);
}
}
else
x++,update(1,x,y);
}
}
return 0;
}