40pts提高组最简单的题都不会做的fw(悬赏关注阿)
查看原帖
40pts提高组最简单的题都不会做的fw(悬赏关注阿)
520544
Phrvth楼主2022/11/12 23:49

自认为代码写得挺好看

谢谢你们

#include<bits/stdc++.h>

using namespace std;
#define int long long
const int MAXN = 1e5 + 7, INF = 1e9 + 7, MAXlog = 25;
int lo[MAXN];
inline void log_2() {
	for (int i = 1; i <= MAXN; i++) 
		lo[i] += lo[i - 1] + (1 << lo[i-1] == i);
}
inline void get_max(int a[], int n, int dp[][MAXlog]) {//a数组传输到ans数组 
	for (int i = 1; (1 << i) <= n; i++) 
		for (int j = 1; j + (1 << i) - 1 <= n; j++) 
			dp[j][i] = -INF;
	for (int i = 1; i <= n ; i++) dp[i][0] = a[i];
	for (int i = 1; (1 << i) <= n; i++) 
		for (int j = 1; j + (1 << i) - 1 <= n; j++)
			dp[j][i] = max(dp[j][i-1], dp[j + (1 << i - 1)][i - 1]);
}
inline void get_min(int a[], int n, int dp[][MAXlog]) {//a数组传输到ans数组 
	for (int i = 1; (1 << i) <= n; i++) 
		for (int j = 1; j + (1 << i) - 1 <= n; j++) 
			dp[j][i] = INF;
	for (int i = 1; i <= n ; i++) dp[i][0] = a[i];
	for (int i = 1; (1 << i) <= n; i++) 
		for (int j = 1; j + (1 << i) - 1 <= n; j++)
			dp[j][i] = min(dp[j][i-1], dp[j + (1 << i - 1)][i - 1]);
}
inline int maxx(int l, int r, int a[][MAXlog]) {
	int k = lo[r - l + 1] - 1;//注意-1
	return max(a[l][k], a[r - (1 << k) + 1][k]); 
}
inline int minn(int l, int r, int a[][MAXlog]) {
	int k = lo[r - l + 1] - 1;//注意-1
	return min(a[l][k], a[r - (1 << k) + 1][k]); 
}
int n, m, q;
int a[MAXN], b[MAXN];
int bmax[MAXN][MAXlog], bmin[MAXN][MAXlog];
int afumax[MAXN][MAXlog], amin[MAXN][MAXlog], azsmin[MAXN][MAXlog], amax[MAXN][MAXlog];
int dt[MAXN];//临时数组 
signed main() {
	log_2();
	scanf("%lld%lld%lld", &n, &m, &q);
	for (int i = 1; i <= n; i++) scanf("%lld", a + i);
	for (int i = 1; i <= m; i++) scanf("%lld", b + i);
	for (int i = 1; i <= n; i++) dt[i] = a[i];
	get_max(dt, n, amax), get_min(dt, n, amin);//a区间的最大最小值 
	for (int i = 1; i <= m ;i++) dt[i] = b[i];
	get_max(dt, m, bmax), get_min(dt, m, bmin);//b区间的最大最小值 
	for (int i = 1; i <= n; i++) dt[i] = (a[i] > 0 ? -INF : a[i]);
	get_max(dt, n, afumax);//a区间最大负数 
	for (int i = 1; i <= n; i++) dt[i] = (a[i] < 0 ? INF : a[i]);
	get_min(dt, n, azsmin);//a区间最小正数 
	while(q--) {
		int l1, r1, l2 ,r2;
		scanf("%lld%lld%lld%lld", &l1, &r1, &l2, &r2);
		int y_min = minn(l2, r2, bmin), y_max = maxx(l2, r2, bmax);
		int ans = -INF;
		if(y_min >= 0) ans = max(ans, y_min * maxx(l1, r1, amax));
		else if(y_min < 0) ans = max(ans, y_min * minn(l1, r1, azsmin));
		if(y_max >= 0) ans = max(ans, y_max * maxx(l1, r1, afumax));
		else if(y_max < 0) ans = max(ans, y_max * minn(l1, r1, amin));
		printf("%lld\n", ans);
	}
	return 0;
}
/*
1.x>0 y>0 x为最大的数
2.x>0 y<0 x为最小的正数 

3.x<0 y>0 x为最大的负数
4.x<0 y<0 x为最小的数
包括0 
*/
2022/11/12 23:49
加载中...