题目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
典型的线段树单点更新与区间最大(小)值,没什么奥妙,但是自己还是打挫了,连WA带T13发,233,最终在一位小姐姐的指导小改掉一些细节错误成功A一发
附上AC代码:1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<string> 5 #include<cstring> 6 7 using namespace std; 8 9 const int MAXNODE = (1<<20)+5; 10 const int MAX = 2e7+10;//2*10^6+10 11 const int INF = 0x7fffffff; 12 13 struct NODE{ 14 int maxvalue, minvalue; 15 int left, right; 16 }node[MAXNODE]; 17 18 int father[MAX]; 19 20 21 void BuildTree(int i, int left, int right) 22 { 23 node[i].minvalue = INF; 24 node[i].maxvalue = -INF; 25 node[i].left = left; 26 node[i].right = right; 27 if(right == left) 28 { 29 father[left] = i; 30 return; 31 } 32 BuildTree(i<<1, left, (int)(floor(left+right)/2.0)); 33 BuildTree((i<<1)+1, (int)(floor(left+right)/2.0)+1, right); 34 } 35 36 37 //自底向上更新 38 void UpdateTree(int ri) 39 { 40 if(ri <= 1) 41 return; 42 int fi = ri/2; 43 int a = node[fi<<1].maxvalue; 44 int b = node[(fi<<1)+1].maxvalue; 45 node[fi].maxvalue = max(a, b); 46 a = node[fi<<1].minvalue; 47 b = node[(fi<<1)+1].minvalue; 48 node[fi].minvalue = min(a, b); 49 UpdateTree(ri/2); 50 } 51 52 53 int Max, Min; 54 55 56 //自顶向上查询 57 void Query_max(int i, int l, int r) 58 { 59 if(node[i].left == l && node[i].right == r) 60 { 61 Max = max(Max, node[i].maxvalue); 62 return; 63 } 64 65 i <<= 1; 66 if(l <= node[i].right) 67 { 68 if(r <= node[i].right) 69 { 70 Query_max(i, l, r); 71 } 72 else 73 { 74 Query_max(i, l, node[i].right); 75 } 76 } 77 i++; 78 if(r >= node[i].left) 79 { 80 if(l >= node[i].left) 81 { 82 Query_max(i, l, r); 83 } 84 else 85 { 86 Query_max(i, node[i].left, r); 87 } 88 } 89 } 90 91 92 void Query_min(int i, int l, int r) 93 { 94 if(node[i].left == l && node[i].right == r) 95 { 96 Min = min(Min, node[i].minvalue); 97 return; 98 } 99 100 i <<= 1; 101 if(l <= node[i].right) 102 { 103 if(r <= node[i].right) 104 { 105 Query_min(i, l, r); 106 } 107 else 108 { 109 Query_min(i, l, node[i].right); 110 } 111 } 112 i++; 113 if(r >= node[i].left) 114 { 115 if(l >= node[i].left) 116 { 117 Query_min(i, l, r); 118 } 119 else 120 { 121 Query_min(i, node[i].left, r); 122 } 123 } 124 } 125 126 127 int main() 128 { 129 int k, t, n, g, a, b, c; 130 long long ans; 131 ios::sync_with_stdio(false); 132 cin>>t; 133 //cout<<INF<<-INF<<endl; 134 while(t--) 135 { 136 cin>>k; 137 BuildTree(1, 1, 1<<k); 138 for(int i = 1; i <= 1<<k; i++) 139 { 140 cin>>g; 141 node[father[i]].maxvalue = node[father[i]].minvalue = g; 142 UpdateTree(father[i]); 143 } 144 cin>>n; 145 for(int i = 1; i <= n; i++) 146 { 147 Max = -INF; 148 Min = INF; 149 cin>>a>>b>>c; 150 if(a == 1) 151 { 152 Query_max(1, b+1, c+1); 153 Query_min(1, b+1, c+1); 154 //cout<<Max<<" "<<Min<<endl; 155 if(Max <= 0) 156 { 157 ans = (long long)Max*Max; 158 cout<<ans<<endl; 159 } 160 else if(Min >= 0) 161 { 162 ans = (long long)Min*Min; 163 cout<<ans<<endl; 164 } 165 else 166 { 167 ans = (long long)Min*Max; 168 cout<<ans<<endl; 169 } 170 } 171 else if(a == 2) 172 { 173 node[father[b+1]].maxvalue = node[father[b+1]].minvalue = c; 174 UpdateTree(father[b+1]); 175 } 176 } 177 } 178 return 0; 179 }