CSP-S2022 T2策略游戏 这题不知道哪里写挂了,竟然只错了一个点,这个点的询问到了数组的边界,但是我调了好久不知道错哪了 ST表做法,数组命名z/f表示正/负 码风优良
#include<cstdio>
#include<iostream>
using namespace std;
#define int long long
const int INF = 9e18;
const int N = 1e5+5;
const int M = 16;
int n, m, q;
int a[N], az[N], af[N], sum0[N];
int maxaz[N][M+5], maxaf[N][M+5], minaz[N][M+5], minaf[N][M+5];
int maxb[N][M+5], minb[N][M+5], lg[N];
inline int read()
{
int x=0, f=1; char c=getchar();
while (c<'0' || c>'9') { if (c=='-') f=-1; c=getchar(); }
while (c>='0' && c<='9') { x = (x<<3)+(x<<1)+c-48; c=getchar(); }
return f*x;
}
void initMax(int (&targ)[N][M+5], int len)
{
for (int i=1; i<=M; ++i){
for (int j=1; j<=len; ++j){
if (j+(1<<i)-1>len) break ;
targ[j][i] = max(targ[j][i-1], targ[j+(1<<(i-1))][i-1]);
}
}
}
void initMin(int (&targ)[N][M+5], int len)
{
for (int i=1; i<=M; ++i){
for (int j=1; j<=len; ++j){
if (j+(1<<i)-1>len) break ;
targ[j][i] = min(targ[j][i-1], targ[j+(1<<(i-1))][i-1]);
}
}
}
int getMin(int (&targ)[N][M+5], int l, int r)
{
int len = lg[r-l+1];
// printf("len:%d t1:%d t2:%d\n", len, l, r-(1<<len)+1);
return min(targ[l][len], targ[r-(1<<len)+1][len]);
}
int getMax(int (&targ)[N][M+5], int l, int r)
{
int len = lg[r-l+1];
return max(targ[l][len], targ[r-(1<<len)+1][len]);
}
signed main()
{
n=read(), m=read(), q=read();
for (int i=1; i<=n; ++i){
a[i] = read();
sum0[i] = sum0[i-1]+(a[i]==0);
if (a[i]>=0){
maxaz[i][0] = a[i];
minaz[i][0] = a[i];
maxaf[i][0] = -INF;
minaf[i][0] = INF;
}
else {
maxaz[i][0] = -INF;
minaz[i][0] = INF;
maxaf[i][0] = a[i];
minaf[i][0] = a[i];
}
}
for (int i=1; i<=m; ++i)
maxb[i][0] = minb[i][0] = read();
lg[1] = 0;
for (int i=2; i<=n; ++i) lg[i] = lg[i>>1]+1;
initMin(minb, m), initMin(minaz, n), initMin(minaf, n);
initMax(maxb, m), initMax(maxaf, n), initMax(maxaz, n);
// for (int i=0; i<=M && (1<<i)<=n; ++i){
// printf("%d:", (1<<i));
// for (int j=1; j<=n; ++j)
// printf("%d ", maxaz[j][i]);
// puts("");
// }
int ans, l1, r1, l2, r2;
while (q--){
l1=read(), r1=read(), l2=read(), r2=read();
ans = -INF;
if (getMax(maxaz, l1, r1)!=-INF){
// printf("++%d %d\n", getMax(maxaz, l1, r1), getMin(minb, l2, r2));
if (getMin(minb, l2, r2)>=0)
ans = max(ans, getMax(maxaz, l1, r1)*getMin(minb, l2, r2));
else
ans = max(ans, getMin(minaz, l1, r1)*getMin(minb, l2, r2));
}
if (sum0[r1]-sum0[l1-1]>0) ans = max(ans, 0ll);
if (getMax(maxaf, l1, r1)!=-INF){
// printf("--%d %d\n", getMax(maxaf, l1, r1), getMax(maxb, l2, r2));
if (getMax(maxb, l2, r2)>0)
ans = max(ans, getMax(maxaf, l1, r1)*getMax(maxb, l2, r2));
else
ans = max(ans, getMin(minaf, l1, r1)*getMax(maxb, l2, r2));
}
printf("%lld\n", ans);
}
return 0;
}