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

来源:互联网 发布:易建联nba生涯数据 编辑:程序博客网 时间:2024/06/07 05:34

题目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, -2≤ y < 2k)

输出

For each query 1, output a line contains an integer, indicating the answer.

样例输入
131 1 2 2 1 1 2 251 0 71 1 22 1 22 2 21 1 2
样例输出
114

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

题意:给你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-9ll 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);elseupdata(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;}


阅读全文
0 0
原创粉丝点击