mirror of
https://gitcode.com/Zengtudor/alg2025.git
synced 2025-10-17 21:42:25 +00:00
feat: 实现P8818题的解决方案
添加基于稀疏表的区间查询功能,用于处理不同情况下的最大值、最小值和零值判断 实现题目要求的各种情况组合计算逻辑
This commit is contained in:
parent
e75613ac10
commit
b8cf43f694
@ -1,3 +1,173 @@
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <istream>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
using ll = int64_t;
|
||||
|
||||
#define pv(v)\
|
||||
do {\
|
||||
std::cout<<#v<<":\n";\
|
||||
for(ll i=0;i<v.size();i++){\
|
||||
for(ll j=0;j<v[i].size();j++){\
|
||||
printf("[%lld][%lld]=%lld\n",i,j,v[i][j]);\
|
||||
}\
|
||||
}\
|
||||
std::cout<<"\n";\
|
||||
}while (0)
|
||||
|
||||
#define p(v)\
|
||||
do{\
|
||||
printf(#v" :%lld\n",(v));\
|
||||
}while(0)\
|
||||
|
||||
const ll inf = 1e9+7;
|
||||
ll n,m,q;
|
||||
std::vector<ll> a,b;
|
||||
|
||||
struct BT{
|
||||
std::vector<std::vector<ll>> vmax, vmin, vupmin, vdownmax;
|
||||
std::vector<std::vector<bool>> vis0;
|
||||
ll vsize;
|
||||
|
||||
inline BT(const std::vector<ll> &v){
|
||||
vsize = ceil(log2(v.size()));
|
||||
vmax.resize(v.size(),std::vector<ll>(vsize+1, -inf));
|
||||
vmin.resize(v.size(),std::vector<ll>(vsize+1,inf));
|
||||
vupmin.resize(v.size(),std::vector<ll>(vsize+1,inf));
|
||||
vdownmax.resize(v.size(),std::vector<ll>(vsize+1,-inf));
|
||||
vis0.resize(v.size(),std::vector<bool>(vsize+1,0));
|
||||
for(ll i=0;i<v.size();i++){
|
||||
vmax[i][0]=vmin[i][0]=v[i];
|
||||
if(v[i]>0){
|
||||
vupmin[i][0]=v[i];
|
||||
}else if(v[i]<0){
|
||||
vdownmax[i][0]=v[i];
|
||||
}
|
||||
vis0[i][0]=!v[i];
|
||||
}
|
||||
for(ll j=1;j<=vsize;j++){
|
||||
for(ll i=0;i+(1ll<<j)-1<v.size();i++){
|
||||
vmax[i][j]=std::max(vmax[i][j-1],vmax[i+(1ull<<(j-1))][j-1]);
|
||||
vmin[i][j]=std::min(vmin[i][j-1],vmin[i+(1ull<<(j-1))][j-1]);
|
||||
vdownmax[i][j]=std::max(vdownmax[i][j-1],vdownmax[i+(1ull<<(j-1))][j-1]);
|
||||
vupmin[i][j]=std::min(vupmin[i][j-1],vupmin[i+(1ull<<(j-1))][j-1]);
|
||||
vis0[i][j]= vis0[i][j-1] || vis0[i+(1ull<<(j-1))][j-1];
|
||||
}
|
||||
}
|
||||
// pv(vmax);
|
||||
// pv(vmin);
|
||||
// pv(vupmin);
|
||||
// pv(vdownmax);
|
||||
}
|
||||
inline ll getmax(const std::vector<std::vector<ll>> &v,const ll l,const ll r){
|
||||
const ll lg = log2(r-l+1);
|
||||
return std::max(
|
||||
v[l][lg],
|
||||
v[r-(1ull<<lg)+1][lg]
|
||||
);
|
||||
}
|
||||
inline ll getmin(const std::vector<std::vector<ll>> &v,const ll l,const ll r){
|
||||
const ll lg = log2(r-l+1);
|
||||
return std::min(
|
||||
v[l][lg],
|
||||
v[r-(1ull<<lg)+1][lg]
|
||||
);
|
||||
}
|
||||
inline ll getvmax(ll l,ll r){
|
||||
return getmax(vmax, l, r);
|
||||
}
|
||||
inline ll getvmin(ll l,ll r){
|
||||
return getmin(vmin,l,r);
|
||||
}
|
||||
inline ll getdownmax(ll l,ll r){
|
||||
return getmax(vdownmax, l, r);
|
||||
}
|
||||
inline ll getupmin(ll l,ll r){
|
||||
return getmin(vupmin, l, r);
|
||||
}
|
||||
inline ll getis0(ll l,ll r){
|
||||
const ll lg = log2(r-l+1);
|
||||
return vis0[l][lg] || vis0[r-(1ull<<lg)+1][lg];
|
||||
}
|
||||
};
|
||||
|
||||
int main(){
|
||||
std::iostream::sync_with_stdio(false);
|
||||
std::cin.tie(nullptr);
|
||||
|
||||
std::cin>>n>>m>>q;
|
||||
a.resize(n+1);
|
||||
b.resize(m+1);
|
||||
|
||||
for(ll i=1;i<=n;i++)std::cin>>a[i];
|
||||
for(ll i=1;i<=m;i++)std::cin>>b[i];
|
||||
BT A=a, B=b;
|
||||
for(ll i=1;i<=q;i++){
|
||||
ll ans=0;
|
||||
ll l1,r1,l2,r2;
|
||||
std::cin>>l1>>r1>>l2>>r2;
|
||||
ll amax = A.getvmax(l1, r1),
|
||||
amin = A.getvmin(l1, r1),
|
||||
aupmin = A.getupmin(l1, r1),
|
||||
adownmax = A.getdownmax(l1, r1);
|
||||
ll bmax = B.getvmax(l2, r2),
|
||||
bmin = B.getvmin(l2, r2),
|
||||
bupmin = B.getupmin(l2, r2),
|
||||
bdownmax = B.getdownmax(l2, r2);
|
||||
ll aop,bop;
|
||||
if(amin>0){
|
||||
aop=1;
|
||||
}else if(amax<0){
|
||||
aop=2;
|
||||
}else if(amin<0&&amax>0){
|
||||
aop=3;
|
||||
}else{
|
||||
aop=4;
|
||||
}
|
||||
if(bmin>0){
|
||||
bop=1;
|
||||
}else if(bmax<0){
|
||||
bop=2;
|
||||
}else if(bmin<0&&bmax>0){
|
||||
bop=3;
|
||||
}else{
|
||||
bop=4;
|
||||
}
|
||||
if(aop==1&&bop==1){
|
||||
ans+=amax*bmin;
|
||||
}else if(aop==1&&bop==2){
|
||||
if(A.getis0(l1, r1));
|
||||
else ans+=amin*bmin;
|
||||
}else if(aop==1 && bop==3){
|
||||
if(A.getis0(l1, r1));
|
||||
else ans+=amin*bmin;
|
||||
}else if(aop==2&&bop==1){
|
||||
if(A.getis0(l1, r1));
|
||||
else ans+=amax*bmax;
|
||||
}else if(aop==2&&bop==2){
|
||||
ans+=amin*bmax;
|
||||
}else if(aop==2&&bop==3){
|
||||
if(A.getis0(l1, r1));
|
||||
else ans+=amax*bmax;
|
||||
}else if(aop==3&&bop==1){
|
||||
ans+=amax*bmin;
|
||||
}else if(aop==3&&bop==2){
|
||||
ans+=amin*bmax;
|
||||
}else if(aop==3&&bop==3){
|
||||
if(!A.getis0(l1, r1))ans+=std::max(
|
||||
aupmin*bmin,
|
||||
adownmax*bmax
|
||||
);
|
||||
}
|
||||
std::cout<<ans<<"\n";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
不考虑0
|
||||
@ -9,7 +179,7 @@ A全负,B全负 => A取最小值,B取最大值
|
||||
A全负,B有正有负 => A取最大值,B取最大值
|
||||
A有正有负,B全正 => A取最大值,B取最小值
|
||||
A有正有负,B全负 => A取最小值,B取最大值
|
||||
A有正有负,有正有负 => max(A的正数最小*B的负数小 , A的负数最大*B的正数最大)
|
||||
A有正有负,有正有负 => max(A的正数最小*Bmin , A的负数最大*Bmax)
|
||||
|
||||
A有0的情况
|
||||
A>=0,B>0 => Amax * Bmin
|
||||
@ -23,8 +193,3 @@ A><=0, B<0 => Amin * Bmax
|
||||
A><=0, B><0 => max()
|
||||
|
||||
*/
|
||||
|
||||
|
||||
int main(){
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user