线段树 ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛 HihoCoder 1586

来源:互联网 发布:股市九宫图软件 编辑:程序博客网 时间:2024/05/17 08:14

#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, -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

题意:给出一个数组,有多次查询,查询类型1 : 问区间(l,r)里找两个数使乘积最小,(可以重复使用数字)

查询类型2:把下标为 x 的值该为 c

思路:用线段树维护一个区间的最大值和最小值,查询答案的时候定位到这个区间,然后根据最大值和最小值的正负找到最小的组合,输出答案即可

#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>using namespace std;#define ll long long#define maxn 500005struct Tree{int minn,maxx,l,r;}tree[maxn * 4];int arr[maxn * 4];void push_up(int i){tree[i].maxx = max(tree[i << 1].maxx,tree[i << 1 | 1].maxx);tree[i].minn = min(tree[i << 1].minn,tree[i << 1 | 1].minn);}void build(int l,int r,int i){tree[i].l = l;tree[i].r = r;int mid = (l + r) >> 1;if(l == r){tree[i].maxx = tree[i].minn = arr[l];}else{build(l,mid,i << 1);build(mid + 1,r,i << 1 | 1);push_up(i);}}void update(int x,int c,int i){if(tree[i].l == x && tree[i].r == x){tree[i].maxx = tree[i].minn = c;return ;}int mid = (tree[i].l + tree[i].r) >> 1;if(mid >= x)update(x,c,i << 1);else if(mid < x){update(x,c,i << 1 | 1);}else{update(x,c,i << 1);update(x,c,i << 1 | 1);}push_up(i);}Tree query(int x,int y,int i){if(x <= tree[i].l && tree[i].r <= y){return tree[i];}int mid = (tree[i].l + tree[i].r) >> 1;if(mid >= y){return query(x,y,i << 1);}else if(mid < x){return query(x,y,i << 1 | 1);}else{Tree t1,t2,tmp;t1 = query(x,y,i << 1);t2 = query(x,y,i << 1 | 1);tmp.maxx = max(t1.maxx,t2.maxx);tmp.minn = min(t1.minn,t2.minn);return tmp; }}int main(){int n,m,a,b,c,t;ll ans;scanf("%d",&t);while(t--){scanf("%d",&n);n = 1 << n;for(int i = 1;i <= n;i++){scanf("%d",&arr[i]);}build(1,n,1);scanf("%d",&m);while(m--){scanf("%d %d %d",&a,&b,&c);if(a == 1){Tree tmp = query(b + 1,c + 1,1);if(tmp.minn <= 0 && tmp.maxx >= 0){ans = (ll)tmp.maxx * tmp.minn;}else if(tmp.minn < 0 && tmp.maxx <= 0)ans = (ll)tmp.maxx * tmp.maxx;elseans = (ll)tmp.minn * tmp.minn;printf("%lld\n",ans);}else{update(b + 1,c,1);}}}return 0;}

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