废话不多说,直接上代码
//八个ST表维护最大最小值
#include <cstdio>
// #include <windows.h>
#include <iostream>
using namespace std;
const int N = 1e+6 + 1000;
int INF = 0;
int A[N], B[N];
//true代表是正数 false代表负数
int A_true_max[N][30], A_false_max[N][30],
A_true_min[N][30], A_false_min[N][30];
int B_true_max[N][30], B_false_max[N][30],
B_true_min[N][30], B_false_min[N][30];
int num_a, num_b, q;
int logx[N];
//调试的时候出错了,所以手打的max与min
int _max(int x, int y) {
return x > y ? x : y;
}
int _min(int x, int y) {
return x < y ? x : y;
}
// 预处理
void prepare() {
// INF = 1073741824;
cin >> num_a >> num_b >> q;
for (int i = 1; i <= num_a; i++) cin >> A[i];
for (int i = 1; i <= num_b; i++) cin >> B[i];
int maxn0 = max(num_a, num_b);
logx[0] = -1;
for (int i = 1; i <= maxn0; i++) {
logx[i] = logx[i >> 1] + 1;
}
for (int i = 1; i <= num_a; i++) {
//调正数与负数的初始值
// 主要运用了在合并的时候会滚掉一部分数的情况
// 在正数中 若为正数 不变 如果为负数 赋值为-1 方便以后找全局最大最小值
A_true_max[i][0] = (A[i] >= 0 ? A[i] : -1);
//若为找最小值 就赋值为极大值 再找最小值的时候会被滚走
A_true_min[i][0] = (A[i] >= 0 ? A[i] : 1073741824);
// 负数中情况与正数相似 但相反
A_false_max[i][0] = (A[i] <= 0 ? A[i] : -1073741824);
A_false_min[i][0] = (A[i] <= 0 ? A[i] : 1);
}
// 同上
for (int i = 1; i <= num_b; i++) {
B_true_max[i][0] = (B[i] >= 0 ? B[i] : -1);
B_true_min[i][0] = (B[i] >= 0 ? B[i] : 1073741824);
B_false_max[i][0] = (B[i] <= 0 ? B[i] : -1073741824);
B_false_min[i][0] = (B[i] <= 0 ? B[i] : 1);
}
// ST表初始化
for (int j = 1; j <= logx[num_a]; j++) {
for (int i = 1; i + (1 << j) - 1 <= num_a; i++) {
A_true_max[i][j] = _max(A_true_max[i][j-1], A_true_max[i + (1 << (j - 1))][j-1]);
A_true_min[i][j] = _min(A_true_min[i][j-1], A_true_min[i + (1 << (j - 1))][j-1]);
A_false_max[i][j] = _max(A_false_max[i][j-1], A_false_max[i + (1 << (j - 1))][j-1]);
A_false_min[i][j] = _min(A_false_min[i][j-1], A_false_min[i + (1 << (j - 1))][j-1]);
}
}
for (int j = 1; j <= logx[num_b]; j++) {
for (int i = 1; i + (1 << j) - 1 <= num_a; i++) {
B_true_max[i][j] = _max(B_true_max[i][j-1], B_true_max[i + (1 << (j - 1))][j-1]);
B_true_min[i][j] = _min(B_true_min[i][j-1], B_true_min[i + (1 << (j - 1))][j-1]);
B_false_max[i][j] = _max(B_false_max[i][j-1], B_false_max[i + (1 << (j - 1))][j-1]);
B_false_min[i][j] = _min(B_false_min[i][j-1], B_false_min[i + (1 << (j - 1))][j-1]);
}
}
}
// 这里是ST表的查询
// 正数表为true 负数表为false
int max_A_true(int l, int r) {
int k = logx[r - l + 1];
return _max(A_true_max[l][k], A_true_max[r - (1 << k) + 1][k]);
}
int min_A_true(int l, int r) {
int k = logx[r - l + 1];
return _min(A_true_min[l][k], A_true_min[r - (1 << k) + 1][k]);
}
int max_A_false(int l, int r) {
int k = logx[r - l + 1];
return _max(A_false_max[l][k], A_false_max[r - (1 << k) + 1][k]);
}
int min_A_false(int l, int r) {
int k = logx[r - l + 1];
return _min(A_false_min[l][k], A_false_min[r - (1 << k) + 1][k]);
}
int max_B_true(int l, int r) {
int k = logx[r - l + 1];
return _max(B_true_max[l][k], B_true_max[r - (1 << k) + 1][k]);
}
int min_B_true(int l, int r) {
int k = logx[r - l + 1];
return _min(B_true_min[l][k], B_true_min[r - (1 << k) + 1][k]);
}
int max_B_false(int l, int r) {
int k = logx[r - l + 1];
return _max(B_false_max[l][k], B_false_max[r - (1 << k) + 1][k]);
}
int min_B_false(int l, int r) {
int k = logx[r - l + 1];
return _min(B_false_min[l][k], B_false_min[r - (1 << k) + 1][k]);
}
// 调试的代码
void _print() {
cout << "logx:" << endl;
for(int i = 0; i <= max(num_a, num_b); i++) {
cout << logx[i] << " ";
}
cout << endl;
cout << "A_true_max" << endl;
for (int j = 0; j <= logx[num_a]; j++){
for(int i = 1; i <= num_a; i++) {
cout << A_true_max[i][j] << " ";
}
cout << endl;
}
cout << "A_true_min" << endl;
for (int j = 0; j <= logx[num_a]; j++){
for(int i = 1; i <= num_a; i++) {
cout << A_true_min[i][j] << " ";
}
cout << endl;
}
cout << "A_false_max" << endl;
for (int j = 0; j <= logx[num_a]; j++){
for(int i = 1; i <= num_a; i++) {
cout << A_false_max[i][j] << " ";
}
cout << endl;
}
cout << "A_false_min" << endl;
for (int j = 0; j <= logx[num_a]; j++){
for(int i = 1; i <= num_a; i++) {
cout << A_false_min[i][j] << " ";
}
cout << endl;
}
cout << "B_true_max" << endl;
for (int j = 0; j <= logx[num_b]; j++){
for(int i = 1; i <= num_b; i++) {
cout << B_true_max[i][j] << " ";
}
cout << endl;
}
cout << "B_true_min" << endl;
for (int j = 0; j <= logx[num_b]; j++){
for(int i = 1; i <= num_b; i++) {
cout << B_true_min[i][j] << " ";
}
cout << endl;
}
cout << "B_false_max" << endl;
for (int j = 0; j <= logx[num_b]; j++){
for(int i = 1; i <= num_b; i++) {
cout << B_false_max[i][j] << " ";
}
cout << endl;
}
cout << "B_false_min" << endl;
for (int j = 0; j <= logx[num_b]; j++){
for(int i = 1; i <= num_b; i++) {
cout << B_false_min[i][j] << " ";
}
cout << endl;
}
}
int main(){
// freopen("game0.in", "r", stdin);
ios::sync_with_stdio(false);
// printf("hellowwarld");
prepare();
// _print();
int la, ra, lb, rb;
while (q--) {
cin >> la >> ra >> lb >> rb;
// 分别找A,B的全局最大值和最小值
int max_a = max_A_true(la, ra),
min_a = min_A_false(la, ra),
max_b = max_B_true(lb, rb),
min_b = min_B_false(lb, rb);
if(max_a < 0) max_a = max_A_false(la, ra);
if(min_a > 0) min_a = min_A_true(la, ra);
if(max_b < 0) max_b = max_B_false(lb, rb);
if(min_b > 0) min_b = min_B_true(lb, rb);
// 这里是决策的几种情况,可以见下图
// cout << "max_a: " << max_a << " min_a: " << min_a << " max_b: " << max_b << " min_b: " << min_b << endl;
// 情况一
if(min_a >= 0 && min_b >= 0) cout << max_a * min_b;
// 情况二
else if(max_a <= 0 && max_b <= 0) cout << min_a * max_b;
// 情况三
else if(max_a >= 0 && min_a <= 0 && min_b >= 0) cout << max_a * min_b;
// 情况四
else if(max_a >= 0 && min_a <= 0 && max_b <= 0) cout << min_a * max_b;
// 情况五
else if(min_a >= 0 && max_b >= 0 && min_b <= 0) cout << min_a * min_b;
// 情况六
else if(max_a <= 0 && max_b >= 0 && min_b <= 0) cout << max_a * max_b;
// 情况七
else if(max_a <= 0 && min_b >= 0) cout << max_a * max_b;
// 情况八
else if(min_a >= 0 && max_b <= 0) cout << min_a * min_b;
// 情况九
else if(max_a >= 0 && min_a <= 0 && max_b >= 0 && min_b <= 0) cout << _max(min_A_true(la, ra) * min_b, max_A_false(la, ra) * max_b);
cout << endl;
}
// fclose(stdin);
}
这里是那几种情况
感谢大佬参观