您的位置:首页 > 理论基础 > 计算机网络

ACM-ICPC北京赛区(2017)网络赛-题目9 : Minimum(线段树)

2017-09-23 22:13 615 查看


题目9 : 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


比赛已经结束,去题库提交。

题意:给你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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐