暴打8个ST表,样例过了,但是爆0
查看原帖
暴打8个ST表,样例过了,但是爆0
588574
Edge_orphan楼主2022/11/11 21:40

废话不多说,直接上代码


//八个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);
}

这里是那几种情况 感谢大佬参观

2022/11/11 21:40
加载中...