#1586 : Minimum
时间限制:1000ms
单点时限:1000ms
内存限制:256MB
描述
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
思路:输出x,y范围内的min(ax,ay),就是找到x--y中最小值pmin和pmax,
如果最小值>=0,最小的结果一定是pmin*pmin;
如果最小值<0,就有两种情况
(1)pmax>=0,最小结果是pmin*pmax,是负数
(2)pmax<0,最小的结果是pmax*pmax,是正数。
参考文章:https://blog.csdn.net/qq_38538733/article/details/78072262
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int INF = 99999999;
const int maxn = 5002000;
typedef long long LL;
LL pmax,pmin;
struct Node{
int l,r;
LL mi,mx;
};
Node t[maxn];
void pushup(int k)
{
t[k].mi=min(t[k*2].mi,t[k*2+1].mi);
t[k].mx=max(t[k*2].mx,t[k*2+1].mx);
}
void build(int k,int l,int r)
{
t[k].l=l;
t[k].r=r;
if(l==r)
{
scanf("%lld",&t[k].mi);
t[k].mx=t[k].mi;
return ;
}
int mid=(l+r)/2;
build(k*2,l,mid);
build(k*2+1,mid+1,r);
pushup(k);
}
void update(int pos,int k,int val)
{
if(t[k].l==t[k].r)
{
t[k].mi=val;
t[k].mx=val;
return ;
}
int mid=(t[k].l+t[k].r)/2;
if(pos<=mid) update(pos,k*2,val);
else update(pos,k*2+1,val);
pushup(k);
}
void query(int k,int l,int r)
{
if(t[k].l==l&&t[k].r==r)
{
pmin=min(pmin,t[k].mi);
pmax=max(pmax,t[k].mx);
return ;
}
int mid=(t[k].l+t[k].r)/2;
if(r<=mid) query(k*2,l,r);
else if(l>mid) query(k*2+1,l,r);
else
{
query(k*2,l,mid);
query(k*2+1,mid+1,r);
}
}
int main(void)
{
int n,m,k,i,j,x,y,z,q,T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&k);
n=1;
for(i=0;i<k;i++) n*=2;
build(1,0,n-1);
scanf("%d",&q);
while(q--)
{
scanf("%d%d%d",&z,&x,&y);
if(z==1)
{
pmin=INF;
pmax=-INF;
query(1,x,y);
if(pmin>=0) printf("%lld\n",pmin*pmin);
else
{
if(pmax>=0) printf("%lld\n",pmax*pmin);
else printf("%lld\n",pmax*pmax);
}
}
else if(z==2)
{
update(x,1,y);
}
}
}
return 0;
}