Problem
给出两个数组A,B,进行q次询问,每次分别给出这两个数组的某个区间l1,r1,l2,r2,也就是\(A_{l1 \sim r1}\)与\(B_{l2\sim r2}\),有两位同学小L和小Q分别从A,B的以上区间中选一个数,而两数乘积为此次操作的分数,小L希望分数大,小Q希望分数小,请问他们每次以最优策略进行游戏,分数将会是多少?(小L先选,且小Q知道小L选了什么)
其中\(1\le n,m,q\le 10^5\)
Solve
不难发现小L如果选了正数,小Q会选最小的数,反之亦然。
但是小L作为先手肯定预判了他的预判,所以他会在脑海中模拟如果选 正数max 正数min 负数max 负数min 小L会选什么,然后计算模拟的四种情况的得分,取最大的方案即可。
然后A,B数组的最值可以直接用ST表维护,对于每个ST表如果有不符合正负的元素直接变成inf或-inf即可。
时间复杂度\(O(n\log n+m\log m)\)
Code
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<cstdlib>
#include<list>
#include<map>
#include<queue>
#include<stack>
#include<vector>
using namespace std;
const long long INF=0x3f3f3f3f3f3f3f3f;
long long n,m,q,a[100005],b[100005];
long long m1[100005][22],m2[100005][22],m3[100005][22],m4[100005][22];//正max/min 负max/min
long long m5[100005][22],m6[100005][22],lg[100005];//max/min
void init(){
for(int i=1;i<=n;i++)m2[i][0]=INF,m3[i][0]=-INF,m4[i][0]=INF;
for(int i=1;i<=m;i++)m5[i][0]=-INF,m6[i][0]=INF;
for(int i=2;i<=max(n,m);i++){
lg[i]=lg[i/2]+1;
}
}
long long pow(long long x){
return 1<<x;
}
long long qlr(int l,int r,int type){
if(type==1)return max(m1[l][lg[r-l+1]],m1[r-pow(lg[r-l+1])+1][lg[r-l+1]]);
if(type==2)return min(m2[l][lg[r-l+1]],m2[r-pow(lg[r-l+1])+1][lg[r-l+1]]);
if(type==3)return max(m3[l][lg[r-l+1]],m3[r-pow(lg[r-l+1])+1][lg[r-l+1]]);
if(type==4)return min(m4[l][lg[r-l+1]],m4[r-pow(lg[r-l+1])+1][lg[r-l+1]]);
if(type==5)return max(m5[l][lg[r-l+1]],m5[r-pow(lg[r-l+1])+1][lg[r-l+1]]);
if(type==6)return min(m6[l][lg[r-l+1]],m6[r-pow(lg[r-l+1])+1][lg[r-l+1]]);
}
int main(){
cin>>n>>m>>q;
init();
for(int i=1;i<=n;i++){
cin>>a[i];
if(a[i]>0){
m1[i][0]=a[i];
m2[i][0]=a[i];
}else {
m3[i][0]=a[i];
m4[i][0]=a[i];
}
}
for(int i=1;i<=m;i++){
cin>>b[i];
m5[i][0]=b[i];
m6[i][0]=b[i];
}
for(int j=1;j<=lg[n];j++){
for(int i=1;i<=n;i++){
if(i+pow(j)-1>n)break;
m1[i][j]=max(m1[i][j-1],m1[i+pow(j-1)][j-1]);
m3[i][j]=max(m3[i][j-1],m3[i+pow(j-1)][j-1]);
m2[i][j]=min(m2[i][j-1],m2[i+pow(j-1)][j-1]);
m4[i][j]=min(m4[i][j-1],m4[i+pow(j-1)][j-1]);
}
}
for(int j=1;j<=lg[m];j++){
for(int i=1;i<=m;i++){
if(i+pow(j)-1>m)break;
m5[i][j]=max(m5[i][j-1],m5[i+pow(j-1)][j-1]);
m6[i][j]=min(m6[i][j-1],m6[i+pow(j-1)][j-1]);
}
}
while(q--){
long long l1,r1,l2,r2,t1=-INF,t2=-INF,t3=-INF,t4=-INF;
cin>>l1>>r1>>l2>>r2;
if(qlr(l1,r1,1)>0){
t1=qlr(l1,r1,1)*qlr(l2,r2,6);
t2=qlr(l1,r1,2)*qlr(l2,r2,6);
}
if(qlr(l1,r1,4)<=0){
t3=qlr(l1,r1,3)*qlr(l2,r2,5);
t4=qlr(l1,r1,4)*qlr(l2,r2,5);
}
cout<<max(max(t1,t2),max(t3,t4))<<endl;
}
return 0;
}
标签:洛谷,r1,min,long,100005,P8818,2022,l1,include
From: https://www.cnblogs.com/yiweixxs/p/18462147