题目链接
描述
You are given a list of integers a0, a1, …, a2^k-1.
You need to support two types of queries:
- Output Minx,y∈[l,r] {ax∙ay}.
- 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 2^k integers, a0, a1, …, a2^k-1 (-2^k ≤ ai < 2^k).
The next line contains a integer (1 ≤ Q < 2^k), indicating the number of queries. Then next Q lines, each line is one of: - 1 l r: Output Minx,y∈[l,r]{ax∙ay}. (0 ≤ l ≤ r < 2^k)
- 2 x y: Let ax=y. (0 ≤ x < 2^k, -2^k ≤ y < 2^k)
输出
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
注意点:
1.<<运算符
举个例子:
5<<2 将5转化为二进制为101,"<<"的意思就是将5的二进制向左移动两位,右边补零
例子中移完之后,变成10100 结果就是20
或者直接记公式:a<<b = a×2^b;
2.>>运算符
同理:a>>b = a ÷ 2 ^ b;
3.线段树的节点数目要开存放数组最大限度的至少4倍(百度一下,你就知道)
4.如果线段树的某个节点为segTree[i],那么左孩子节点为segTree[2i],右孩子节点为segTree[2i+1],原因:
节点是从1开始的,例如第一个节点,没有第0个节点的说法
5.剩下的解释都在代码里
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 150000;
LL t,k,q,z,w,e,mmn,mmx,a[N],mn[N << 2],mx[N << 2];
void build(int k,int l,int r){
if(l == r){
mn[k] = mx[k] = a[l];
return;
}
int mid = l + r >> 1;
build(k * 2,l,mid);
build(k * 2 + 1,mid + 1,r);
mn[k] = min(mn[k * 2],mn[k * 2 + 1]);
mx[k] = max(mx[k * 2],mx[k * 2 + 1]);
return;
}
void update(int k,int l,int r,int L,int R){
if(l == r){
mn[k] = mx[k] = R;
return;
}
int mid = l + r >> 1;
if(mid >= L){
update(k * 2,l,mid,L,R);
}
else{
update(k * 2 + 1,mid + 1,r,L,R);
}
mn[k] = min(mn[k * 2],mn[k * 2 + 1]);
mx[k] = max(mx[k * 2],mx[k * 2 + 1]);
return;
}
int query_min(int k,int l,int r,int L,int R){
if(l > R || r < L){
return INT_MAX;
}
if(L <= l && R >= r){
return mn[k];
}
int mid = l + r >> 1;
return min(query_min(k * 2,l,mid,L,R),query_min(k * 2 + 1,mid + 1,r,L,R));
}
int query_max(int k,int l,int r,int L,int R){
if(l > R || r < L){
return INT_MIN;
}
if(L <= l && R >= r){
return mx[k];
}
int mid = l + r >> 1;
return max(query_max(k * 2,l,mid,L,R),query_max(k * 2 + 1,mid + 1,r,L,R));
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin >> t;
while(t--){
cin >> k;
k = pow(2,k);
for(int i = 0;i < k;i++){//下标从0开始!!
cin >> a[i];
}
build(1,0,k-1);
cin >> q;
while(q--){
cin >> z >> w >> e;
if(z == 1){
mmn = query_min(1,0,k-1,w,e);
mmx = query_max(1,0,k-1,w,e);
if(mmn >= 0){
cout << mmn * mmn << endl;
}
else if(mmx <= 0){
cout << mmx * mmx << endl;
}
else{
cout << mmn * mmx << endl;
}
}
else{
update(1,0,k-1,w,e);
}
}
}
return 0;
}