2021.11.4测试T1-妹子


题目

今天测试,直接挂完了

写了四个小时,最后发现自己题目理解错误了

 

有两个区间,在输入了 \(l\)\(r\) 以后,进行查询

\[ min(max(a_1,a_2,...a_p,b_{p+1},...b_n) \]

即在选定了 \(l\)\(r\) 以后,选定一个\(p\)\(a\)区间从\(1\)\(p\)\(b\)区间从\(p+1\)\(r\)组成一个新的区间,求其最大值,在对不同\(p\)的取值取最小值

\[_{(注意)题目中没有写逗号,导致我认为是求乘了} \]

image

第一种情况当\(a\)的最大值在\(b\)的最大值的前面那么所选区间就一定会经过两个最大值之一 则答案为:

\[min(max(a[l,r]),max(b[l,r])) \]

第二种: \(a\)的最大值在\(b\)的最大值后面
image

(1)当一定经过两个或两个之一时,则答案和第一种相同 (2)两个都不经过
image
则在区间\([x_1,x_2]\)查找\(a\)的最大和\(b\)的最大,再进行比较其位置
image
如果为第一种,则答案为

\[min(max(a[x_1,x_2]),max(b[x_1,x_2])) \]

第二种则继续,利用分治思想

image

直到停止

主要结构:线段树存储最值,区间,加上懒标以及最重要的最值的位置

1:build

 1 void build(int k,int l,int r,int cas){  2     t[k].l=l,t[k].r=r;  3     if(l==r){  4         if(cas==1) t[k].mx=a[l];  5         else t[k].mx=b[l];  6         t[k].pos=l;  7         t[k].lz=0;  8         return;  9  } 10     int mid=(l+r)>>1; 11  build(lc,l,mid,cas); 12     build(rc,mid+1,r,cas); 13  pushup(k); 14 }

2:更新

 1 void update(int k,int l,int r,int val){  2     if(t[k].l>=l && t[k].r<=r){  3         t[k].lz+=val;  4         t[k].mx+=val;  5         return;  6  }  7  pushdown(k);  8     int mid=(t[k].l+t[k].r)>>1;  9         if(l<=mid) update(lc,l,r,val); 10     if(r>mid) update(rc,l,r,val); 11  pushup(k); 12 }    

3:pushup与pushdown

 1 void pushup(int k){  2         if(t[lc].mx>=t[rc].mx){  3             t[k].mx=t[lc].mx;  4             t[k].pos=t[lc].pos;  5  }  6     else{  7         t[k].mx=t[rc].mx;  8         t[k].pos=t[rc].pos;  9  } 10 } 11 void pushdown(int k){ 12     if(t[k].lz){ 13         t[lc].mx+=t[k].lz; 14         t[rc].mx+=t[k].lz; 15         t[lc].lz+=t[k].lz; 16         t[rc].lz+=t[k].lz; 17         t[k].lz=0; 18  } 19 }

4:查询区间位置

node query(int k,int l,int r){ if(t[k].l>=l && t[k].r<=r) return (node){t[k].mx,t[k].pos}; pushdown(k); int mid=(t[k].l+t[k].r)>>1; node res,now;res.mx=-inf; if(l<=mid){ now=query(lc,l,r); if(res.mx<now.mx){ res.mx=now.mx; res.pos=now.pos; } } if(r>mid){ now=query(rc,l,r); if(res.mx<now.mx){ res.mx=now.mx; res.pos=now.pos; } } return res; }

因为有两个区间,所以建树定义结构体:

struct tree{ struct nde{ int l,r,mx,pos,lz;//pos表示最值位置
    }t[N<<2]; void pushup(int k){ if(t[lc].mx>=t[rc].mx){ t[k].mx=t[lc].mx; t[k].pos=t[lc].pos; } else{ t[k].mx=t[rc].mx; t[k].pos=t[rc].pos; } } void pushdown(int k){ if(t[k].lz){ t[lc].mx+=t[k].lz; t[rc].mx+=t[k].lz; t[lc].lz+=t[k].lz; t[rc].lz+=t[k].lz; t[k].lz=0; } } void build(int k,int l,int r,int cas){ t[k].l=l,t[k].r=r; if(l==r){ if(cas==1) t[k].mx=a[l]; else t[k].mx=b[l]; t[k].pos=l; t[k].lz=0; return; } int mid=(l+r)>>1; build(lc,l,mid,cas); build(rc,mid+1,r,cas); pushup(k); } void update(int k,int l,int r,int val){ if(t[k].l>=l && t[k].r<=r){ t[k].lz+=val; t[k].mx+=val; return; } pushdown(k); int mid=(t[k].l+t[k].r)>>1; if(l<=mid) update(lc,l,r,val); if(r>mid) update(rc,l,r,val); pushup(k); } node query(int k,int l,int r){ if(t[k].l>=l && t[k].r<=r) return (node){t[k].mx,t[k].pos}; pushdown(k); int mid=(t[k].l+t[k].r)>>1; node res,now;res.mx=-inf; if(l<=mid){ now=query(lc,l,r); if(res.mx<now.mx){ res.mx=now.mx; res.pos=now.pos; } } if(r>mid){ now=query(rc,l,r); if(res.mx<now.mx){ res.mx=now.mx; res.pos=now.pos; } } return res; } }A,B;//又学到了

最后总代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;  3 #define lc k<<1
 4 #define rc k<<1|1
 5 #define num ch-'0'
 6 void get(int &res)  7 {  8     char ch;bool flag=0;  9     while(!isdigit(ch=getchar()))  10         (ch=='-')&&(flag=true);  11     for(res=num;isdigit(ch=getchar());res=res*10+num);  12     (flag)&&(res=-res);  13 }  14 const int N=6e5+5,inf=0x3f3f3f3f;  15 int n,m,a[N],b[N];  16 struct node{  17     int mx,pos;  18 };  19 struct tree{  20     struct nde{  21         int l,r,mx,pos,lz;  22     }t[N<<2];  23     void pushup(int k){  24         if(t[lc].mx>=t[rc].mx){  25             t[k].mx=t[lc].mx;  26             t[k].pos=t[lc].pos;  27  }  28         else{  29             t[k].mx=t[rc].mx;  30             t[k].pos=t[rc].pos;  31  }  32  }  33     void pushdown(int k){  34         if(t[k].lz){  35             t[lc].mx+=t[k].lz;  36             t[rc].mx+=t[k].lz;  37             t[lc].lz+=t[k].lz;  38             t[rc].lz+=t[k].lz;  39             t[k].lz=0;  40  }  41  }  42     void build(int k,int l,int r,int cas){  43         t[k].l=l,t[k].r=r;  44         if(l==r){  45             if(cas==1) t[k].mx=a[l];  46             else t[k].mx=b[l];  47             t[k].pos=l;  48             t[k].lz=0;  49             return;  50  }  51         int mid=(l+r)>>1;  52  build(lc,l,mid,cas);  53         build(rc,mid+1,r,cas);  54  pushup(k);  55  }  56     void update(int k,int l,int r,int val){  57         if(t[k].l>=l && t[k].r<=r){  58             t[k].lz+=val;  59             t[k].mx+=val;  60             return;  61  }  62  pushdown(k);  63         int mid=(t[k].l+t[k].r)>>1;  64         if(l<=mid) update(lc,l,r,val);  65         if(r>mid) update(rc,l,r,val);  66  pushup(k);  67  }  68     node query(int k,int l,int r){  69         if(t[k].l>=l && t[k].r<=r) return (node){t[k].mx,t[k].pos};  70  pushdown(k);  71         int mid=(t[k].l+t[k].r)>>1;  72         node res,now;res.mx=-inf;  73         if(l<=mid){  74             now=query(lc,l,r);  75             if(res.mx<now.mx){  76                 res.mx=now.mx;  77                 res.pos=now.pos;  78  }  79  }  80         if(r>mid){  81             now=query(rc,l,r);  82             if(res.mx<now.mx){  83                 res.mx=now.mx;  84                 res.pos=now.pos;  85  }  86  }  87         return res;  88  }  89 }A,B;  90 int check(int l,int r){  91     if(l>r) return -inf;  92     node ma=A.query(1,l,r);  93     node mb=B.query(1,l,r);  94     if(ma.pos<=mb.pos) return min(ma.mx,mb.mx);  95     else{  96         return min(min(ma.mx,mb.mx),max(check(mb.pos+1,ma.pos-1),max(A.query(1,l,mb.pos).mx,B.query(1,ma.pos,r).mx)));  97  }  98 }  99 int main(){ 100     //freopen("girl.in","r",stdin); 101     //freopen("girl.out","w",stdout);
102     get(n);get(m); 103     for(int i=1;i<=n;i++) get(a[i]); 104     for(int i=1;i<=n;i++) get(b[i]); 105     A.build(1,1,n,1);B.build(1,1,n,2); 106     char str;int l,r,k; 107     for(int i=1;i<=m;i++){ 108         cin>>str; 109         get(l);get(r);get(k); 110         if(str=='A') A.update(1,l,r,k); 111         else B.update(1,l,r,k); 112         get(l);get(r); 113         cout<<check(l,r)<<endl; 114  } 115     return 0; 116 }


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM