P8818 [CSP-S 2022] 策略游戏

[CSP-S 2022] 策略游戏

实际上就是先手的那个人取保底,后手的那个人取此刻的最佳值。

我一开始以为两个人都取保底,谁想到这么没意思……

那么就是线段树小应用,分别维护区间非负数和负数的最大值以及最小值,具体细节讨论一下即可。

时间复杂度 \(O((n+q)\log n)\)

复健状态的码风比较离谱……我以后写线段树的时候会尽量封装,尽量……

代码:

#include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
namespace Ehnaev{
  inline ll read() {
    ll ret=0,f=1;char ch=getchar();
    while(ch<48||ch>57) {if(ch==45) f=-f;ch=getchar();}
    while(ch>=48&&ch<=57) {ret=(ret<<3)+(ret<<1)+ch-48;ch=getchar();}
    return ret*f;
  }
  inline void write(ll x) {
    static char buf[22];static ll len=-1;
    if(x>=0) {do{buf[++len]=x%10+48;x/=10;}while(x);}
    else {putchar(45);do{buf[++len]=-(x%10)+48;x/=10;}while(x);}
    while(len>=0) putchar(buf[len--]);
  }
}using Ehnaev::read;using Ehnaev::write;

inline void writeln(ll x) {write(x);putchar(10);}

const ll N=1e5;

ll n,m,q;
ll a[N+5],b[N+5];

struct Sgt{
  ll maz,maf,miz,mif;
  #define maz1(p) tree1[p].maz
  #define maf1(p) tree1[p].maf
  #define miz1(p) tree1[p].miz
  #define mif1(p) tree1[p].mif
  #define maz2(p) tree2[p].maz
  #define maf2(p) tree2[p].maf
  #define miz2(p) tree2[p].miz
  #define mif2(p) tree2[p].mif
}tree1[N*4+5],tree2[N*4+5];

inline void Pushup1(ll p) {
  maz1(p)=max(maz1(p<<1),maz1(p<<1|1));
  if(maf1(p<<1)>=0) maf1(p)=maf1(p<<1|1);
  else if(maf1(p<<1|1)>=0) maf1(p)=maf1(p<<1);
  else maf1(p)=max(maf1(p<<1),maf1(p<<1|1));
  if(miz1(p<<1)<0) miz1(p)=miz1(p<<1|1);
  else if(miz1(p<<1|1)<0) miz1(p)=miz1(p<<1);
  else miz1(p)=min(miz1(p<<1),miz1(p<<1|1));
  mif1(p)=min(mif1(p<<1),mif1(p<<1|1));
}

inline void Pushup2(ll p) {
  maz2(p)=max(maz2(p<<1),maz2(p<<1|1));
  if(maf2(p<<1)>=0) maf2(p)=maf2(p<<1|1);
  else if(maf2(p<<1|1)>=0) maf2(p)=maf2(p<<1);
  else maf2(p)=max(maf2(p<<1),maf2(p<<1|1));
  if(miz2(p<<1)<0) miz2(p)=miz2(p<<1|1);
  else if(miz2(p<<1|1)<0) miz2(p)=miz2(p<<1);
  else miz2(p)=min(miz2(p<<1),miz2(p<<1|1));
  mif2(p)=min(mif2(p<<1),mif2(p<<1|1));
}

inline void Build1(ll p,ll l,ll r) {
  if(l==r) {
    if(a[l]>=0) {maz1(p)=miz1(p)=a[l];}
    else {maf1(p)=mif1(p)=a[l];maz1(p)=miz1(p)=-1;}
    return;
  }
  ll mid=(l+r)>>1;Build1(p<<1,l,mid);Build1(p<<1|1,mid+1,r);
  Pushup1(p);
}

inline void Build2(ll p,ll l,ll r) {
  if(l==r) {
    if(b[l]>=0) {maz2(p)=miz2(p)=b[l];}
    else {maf2(p)=mif2(p)=b[l];maz2(p)=miz2(p)=-1;}
    return;
  }
  ll mid=(l+r)>>1;Build2(p<<1,l,mid);Build2(p<<1|1,mid+1,r);
  Pushup2(p);
}

inline Sgt Get1(ll p,ll lp,ll rp,ll l,ll r) {
  if(lp>=l&&rp<=r) {return tree1[p];}
  ll mid=(lp+rp)>>1;
  if(l>mid) return Get1(p<<1|1,mid+1,rp,l,r);
  if(r<=mid) return Get1(p<<1,lp,mid,l,r);
  Sgt tmpl=Get1(p<<1,lp,mid,l,r),tmpr=Get1(p<<1|1,mid+1,rp,l,r),tmp;
  tmp.maz=max(tmpl.maz,tmpr.maz);
  if(tmpl.maf>=0) tmp.maf=tmpr.maf;
  else if(tmpr.maf>=0) tmp.maf=tmpl.maf;
  else tmp.maf=max(tmpl.maf,tmpr.maf);
  if(tmpl.miz<0) tmp.miz=tmpr.miz;
  else if(tmpr.miz<0) tmp.miz=tmpl.miz;
  else tmp.miz=min(tmpl.miz,tmpr.miz);
  tmp.mif=min(tmpl.mif,tmpr.mif);
  return tmp;
}

inline Sgt Get2(ll p,ll lp,ll rp,ll l,ll r) {
  if(lp>=l&&rp<=r) {return tree2[p];}
  ll mid=(lp+rp)>>1;
  if(l>mid) return Get2(p<<1|1,mid+1,rp,l,r);
  if(r<=mid) return Get2(p<<1,lp,mid,l,r);
  Sgt tmpl=Get2(p<<1,lp,mid,l,r),tmpr=Get2(p<<1|1,mid+1,rp,l,r),tmp;
  tmp.maz=max(tmpl.maz,tmpr.maz);
  if(tmpl.maf>=0) tmp.maf=tmpr.maf;
  else if(tmpr.maf>=0) tmp.maf=tmpl.maf;
  else tmp.maf=max(tmpl.maf,tmpr.maf);
  if(tmpl.miz<0) tmp.miz=tmpr.miz;
  else if(tmpr.miz<0) tmp.miz=tmpl.miz;
  else tmp.miz=min(tmpl.miz,tmpr.miz);
  tmp.mif=min(tmpl.mif,tmpr.mif);
  return tmp;
}

int main() {
  
  n=read();m=read();q=read();
  for(ll i=1;i<=n;i++) {a[i]=read();}
  for(ll i=1;i<=m;i++) {b[i]=read();}
  Build1(1,1,n);Build2(1,1,m);
  
  while(q--) {
    ll l1,r1,l2,r2;
    l1=read();r1=read();l2=read();r2=read();
    Sgt tmpa=Get1(1,1,n,l1,r1);
    ll maza=tmpa.maz,mafa=tmpa.maf,miza=tmpa.miz,mifa=tmpa.mif;
    Sgt tmpb=Get2(1,1,m,l2,r2);
    ll mazb=tmpb.maz,mafb=tmpb.maf,mizb=tmpb.miz,mifb=tmpb.mif;
    
//    printf("Testa: %lld %lld %lld %lld\n",maza,mafa,miza,mifa);
//    printf("Testb: %lld %lld %lld %lld\n",mazb,mafb,mizb,mifb);
    
    ll choice_a=0,choice_b=0;
    if(mifb>=0) {
      if(maza>=0) choice_a=maza;
      else choice_a=mafa;
    }
    else {
      if(mazb<0) {
        if(mifa<0) choice_a=mifa;
        else choice_a=miza;
      }
      else {
        if(miza<0) choice_a=mafa;
        else if(mafa>=0) choice_a=miza;
        else if(mifb*miza>mazb*mafa) choice_a=miza;
        else choice_a=mafa;
      }
    }
    
    if(choice_a>=0) {
      if(mifb<0) choice_b=mifb;
      else choice_b=mizb;
    }
    else {
      if(mazb>=0) choice_b=mazb;
      else choice_b=mafb;
    }
    writeln(choice_a*choice_b);
  }
  
  return 0;
}
posted @ 2022-11-23 20:50  Aryper  阅读(212)  评论(0编辑  收藏  举报