ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛 hihocoder #1586 : Minimum-区间查询最值求区间两数最小乘积+单点更新-线段树(结构体版)

#1586 : Minimum

Time Limit:1000ms
Case Time Limit:1000ms
Memory Limit:256MB

Description

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.

Input

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)

Output

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

Sample Input
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
Sample Output
1
1
4
 
 
 

这个题就是区间查询最大值和最小值,通过判断区间最大值和最小值的正负来得到区间最小乘积。

代码:

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<cmath>
 7 #include<queue>
 8 #include<vector>
 9 #define inf 0x7fffffff
10 #define lson l,m,rt<<1
11 typedef long long ll;
12 #define rson m+1,r,rt<<1|1
13 using namespace std;
14 const int maxn=1e6+10;
15 struct node{
16     int left,right,maxx,minn;
17 }tree[maxn*4];
18 int st_min[maxn<<2],st_max[maxn<<2];
19 inline int minn(int a,int b){return a>b?b:a;}
20 inline int maxx(int a,int b){return a>b?a:b;}
21 void PushUP(int rt){
22     st_min[rt]=minn(st_min[rt<<1],st_min[rt<<1|1]);
23     st_max[rt]=maxx(st_max[rt<<1],st_max[rt<<1|1]);
24 }
25 void build(int l,int r,int rt) {
26     if(l==r){
27         scanf("%d",&st_min[rt]);
28         st_max[rt]=st_min[rt];
29         return ;
30     }
31     int m=(l+r)>>1;
32     build(lson);
33     build(rson);
34     PushUP(rt);
35 }
36 void update(int p,int num,int l,int r,int rt){
37        if(l==r){
38         st_max[rt]=num;
39         st_min[rt]=num;
40         return ;
41        }
42        int m=(l+r)>>1;
43        if(p<=m)update(p,num,lson);
44        else update(p,num,rson);
45        PushUP(rt);
46 }
47 int query_min(int L,int R,int l,int r,int rt){
48     if (L<=l&&r<=R){
49         return st_min[rt];
50     }
51     int m=(l+r)>>1;
52     int ret1=inf,ret2=inf;
53     if(L<=m)ret1=query_min(L,R,lson);
54     if(R>m) ret2=query_min(L,R,rson);
55     return minn(ret1,ret2);
56 }
57 int query_max(int L,int R,int l,int r,int rt){
58     if(L<=l&&r<=R){
59        return st_max[rt];
60     }
61     int m=(l+r)>>1;
62     int ret1=-inf,ret2=-inf;
63     if(L<=m)ret1=query_max(L,R,lson);
64     if(R>m) ret2=query_max(L,R,rson);
65     return maxx(ret1,ret2);
66 }
67 int main(){
68     int t;
69     scanf("%d",&t);
70     while(t--){
71         int n,m;
72         scanf("%d",&n);
73         int k=pow(2,n);
74         build(1,k,1);
75         scanf("%d",&m);
76         while(m--){
77             int h,a,b;
78             scanf("%d%d%d",&h,&a,&b);
79             if(h==2)update(a+1,b,1,k,1);
80             else{
81                 ll ans1=query_min(a+1,b+1,1,k,1);
82                 ll ans2=query_max(a+1,b+1,1,k,1);
83                 if(ans1<0&&ans2>=0)
84                     printf("%lld\n",ans2*ans1);
85                 else if(ans1<0&&ans2<0)
86                     printf("%lld\n",ans2*ans2);
87                 else
88                     printf("%lld\n",ans1*ans1);
89             }
90         }
91     }
92     return 0;
93 }
 

猜你喜欢

转载自www.cnblogs.com/ZERO-/p/9130957.html