题目9 : Minimum
-
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
描述
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.
比赛已经结束,去题库提交。
题意:给你n个数,两种询问:
1 x y:从区间中找到两个数,使得这两个数的乘积最小(这两个数可以为同一个数)
2 x y 将a[x]变成y
题解:线段树模板题,线段树维护一个区间最小值和区间最大值。因为数组元素可能为负
所以答案一定是: max*max、 max*min、min*min中的最小值。。
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<vector>
#include<string>
#include<time.h>
#include<math.h>
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<functional>
using namespace std;
#define ll long long
#define inf 1000000000000000000
#define mod 1000000007
#define maxn 1360100
#define lowbit(x) (x&-x)
#define eps 1e-9
ll a[maxn*4];
ll maxs[maxn*4],mins[maxn*4];
void build(ll id,ll l,ll r)
{
ll m;
if(l==r)
{
scanf("%lld",&maxs[id]);
mins[id]=maxs[id];
return ;
}
m=(l+r)/2;
build(id<<1,l,m);
build((id<<1)+1,m+1,r);
maxs[id]=max(maxs[id*2],maxs[id*2+1]);
mins[id]=min(mins[id*2],mins[id*2+1]);
}
ll query(ll id,ll l,ll r,ll L, ll R)
{
ll ret=-inf;
if(l<=L && r>=R)
return maxs[id];
ll m=(L+R)/2;
if(l<=m)
ret=max(ret,query(id<<1,l,r,L,m));
if(r>m)
ret=max(ret,query((id<<1)+1,l,r,m+1,R));
return ret;
}
ll query1(ll id,ll l,ll r,ll L, ll R)
{
ll ret=inf;
if(l<=L && r>=R)
return mins[id];
ll m=(L+R)/2;
if(l<=m)
ret=min(ret,query1(id<<1,l,r,L,m));
if(r>m)
ret=min(ret,query1((id<<1)+1,l,r,m+1,R));
return ret;
}
void updata(ll x,ll y,ll l,ll r,ll id)
{
if(l==r)
{
maxs[id]=y;
mins[id]=y;
return ;
}
ll m=(l+r)/2;
if(x<=m)
updata(x,y,l,m,id*2);
else
updata(x,y,m+1,r,id*2+1);
maxs[id]=max(maxs[id*2],maxs[id*2+1]);
mins[id]=min(mins[id*2],mins[id*2+1]);
}
int main(void)
{
ll n,m,i,j,T;
ll str;
scanf("%lld",&T);
while(T--)
{
ll b,c;
scanf("%lld",&n);
n=(1<<n);
build(1,1,n);
scanf("%lld",&m);
for(i=1;i<=m;i++)
{
scanf("%lld",&str);
scanf("%lld%lld",&b,&c);
b++;c++;
if(str==1)
{
ll ans=query1(1,b,c,1,n)*query1(1,b,c,1,n);
ans=min(ans,query(1,b,c,1,n)*query1(1,b,c,1,n));
ans=min(ans,query(1,b,c,1,n)*query(1,b,c,1,n));
printf("%lld\n",ans);
}
else
c--,updata(b,c,1,n,1);
}
}
return 0;
}