1 条题解
-
1
一道比较简单的思维题。
先不考虑有 0 的情况。
我们设小 L 选择了 ,那么小 Q 会这样选:
- 若小 L 选 :
-
- ,由于乘积只能是正数,小 Q 会选一个绝对值尽量小的 ,小 L 要使得乘积的绝对值尽量大,就会选绝对值最大的 ,即最小负数。
- ,由于乘积可以是负数,小 Q 会选一个绝对值尽量大的 ,小 L 要使得乘积的绝对值尽量小,就会选绝对值最小的 ,即最大负数。
- 若小 L 选 :
-
- ,由于乘积可以是负数,小 Q 会选一个绝对值尽量大的 ,小 L 要使得乘积的绝对值尽量小,就会选绝对值最小的 ,即最小正数。
- ,由于乘积只能是正数,小 Q 会选一个绝对值尽量小的 ,小 L 要使得乘积的绝对值尽量大,就会选绝对值最大的 ,即最大正数。
然后这题就直接成了一个贪心题。给 两个数组都开四个 ST 表,分别存储数列中最大正数,最小正数,最大负数,最小负数即可。0 的情况也不用特判,扔到整数或负数中任意一个情况就行。
#include<bits/stdc++.h> #define int long long using namespace std; int n,m,q,a[100005],b[100005]; struct re{ int a,b,c,d; }; struct nod{ int ST1[100005][20],ST2[100005][20],ST3[100005][20],ST4[100005][20]; void build(int *p,int len){ for(int i=1;i<=len;i++){ ST1[i][0]=ST3[i][0]=p[i]; if(p[i]>0){ ST2[i][0]=p[i]; ST4[i][0]=-2e9; } else { ST2[i][0]=2e9; ST4[i][0]=p[i]; } } for(int j=1;j<=log2(len);j++) for(int i=1;i<=len-(1<<j)+1;i++){ ST1[i][j]=min(ST1[i][j-1],ST1[i+(1<<(j-1))][j-1]); ST2[i][j]=min(ST2[i][j-1],ST2[i+(1<<(j-1))][j-1]); ST3[i][j]=max(ST3[i][j-1],ST3[i+(1<<(j-1))][j-1]); ST4[i][j]=max(ST4[i][j-1],ST4[i+(1<<(j-1))][j-1]); } } re query(int l,int r){ int len=r-l+1; int p=log2(len); int a=min(ST1[l][p],ST1[r-(1<<p)+1][p]); int b=min(ST2[l][p],ST2[r-(1<<p)+1][p]); int c=max(ST3[l][p],ST3[r-(1<<p)+1][p]); int d=max(ST4[l][p],ST4[r-(1<<p)+1][p]); return re{a,b,c,d}; } }A,B; signed main(){ cin>>n>>m>>q; for(int i=1;i<=n;i++)cin>>a[i]; for(int j=1;j<=m;j++)cin>>b[j]; A.build(a,n); B.build(b,m); while(q--){ int l1,l2,r1,r2; cin>>l1>>r1>>l2>>r2; re c1=A.query(l1,r1),c2=B.query(l2,r2); int ans=max(min(c1.c*c2.a,c1.c*c2.c),min(c1.a*c2.c,c1.a*c2.a)); if(c1.b<1e9)ans=max(ans,c1.b*c2.a); if(c1.d>-1e9)ans=max(ans,c1.d*c2.c); cout<<ans<<endl; } return 0; }
求关注喵 !
- 1
信息
- ID
- 325
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 7
- 标签
- 递交数
- 2710
- 已通过
- 524
- 上传者