zoukankan      html  css  js  c++  java
  • 吉司机线段树学习笔记

    先放例题,复杂度不会整坑了暂时

    P6242 【模板】线段树 3

    题解都放代码里了

    调了半个月

      1 /*
      2 吉司机线段树 
      3 */
      4 /*
      5 原来的想法是开一个加标记和一个取min标记,发现懒标记下传只能迭代不能合并
      6 考虑到每次做标记的点满足semx<w<mxA,那么可以开两种加的懒标记
      7 一种是最大值的懒标记,一种是非最大值的懒标记,把两种修改值区分 
      8 */
      9 /*
     10 为啥要开四个懒标记呢
     11 因为对于懒标记传给孙子而言,懒标记的正负会叠加
     12 这时让mxB=max(mxB,mxA) 就是叠加之后去max
     13 忽略了中间只保留正的懒标记的最大值 
     14 */
     15 /*
     16 新加的两个懒标记是对于原来的懒标记的历史取max
     17 而不是对于历史最大值 非最大值的懒标记 
     18 */
     19 #include<bits/stdc++.h> 
     20 using namespace std;
     21 #define LL long long
     22 const int MAXN=5e5+100;
     23 const LL INF=1e18;
     24 inline int read(){
     25     int s=0,w=0;char ch=getchar();
     26     while(ch<'0'||ch>'9')w|=(ch=='-'),ch=getchar();
     27     while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar();
     28     return w?-s:s;
     29 }
     30 #define kd (read())
     31 int n,m;
     32 struct Segment_tree{
     33     #define ls (u<<1)
     34     #define rs (u<<1|1)
     35     LL mxB[MAXN<<2],mxA[MAXN<<2];
     36     LL sm[MAXN<<2],semx[MAXN<<2],cnt[MAXN<<2];
     37     LL lb1[MAXN<<2],lb2[MAXN<<2];
     38     LL hlb1[MAXN<<2],hlb2[MAXN<<2];
     39     inline void up(int u){ 
     40         mxA[u]=max(mxA[ls],mxA[rs]);
     41         sm[u]=sm[ls]+sm[rs];
     42         mxB[u]=max(mxB[u],mxA[u]);
     43         
     44         if(mxA[ls]==mxA[rs])cnt[u]=cnt[ls]+cnt[rs],semx[u]=max(semx[ls],semx[rs]);
     45         else if(mxA[ls]>mxA[rs])cnt[u]=cnt[ls],semx[u]=max(mxA[rs],semx[ls]);
     46         else cnt[u]=cnt[rs],semx[u]=max(mxA[ls],semx[rs]);
     47         
     48         return ;
     49     }
     50     inline void down(int u,int l,int r){
     51         if(l==r)return ;
     52         int mid=l+r>>1;
     53         int lmx=max(mxA[ls],mxA[rs]);
     54         
     55         if(mxA[ls]==lmx){
     56             //LL t=max(0LL,lb1[ls]+hlb1[u]-hlb1[ls]);
     57             hlb1[ls]=max(hlb1[ls],lb1[ls]+hlb1[u]);
     58             mxB[ls]=max(mxB[ls],mxA[ls]+hlb1[u]);
     59             /*
     60             
     61                     这里 因为我更新ch时,ch的懒标记是必须加进ch里的
     62                     所以我不能用t,这样的话会造成本来必须加进去的部分出错 
     63             
     64             */ 
     65 //            mxB[ls]=max(mxB[ls],mxA[ls]+t); 原来错的地方 
     66             mxA[ls]+=lb1[u];
     67             sm[ls]+=cnt[ls]*lb1[u];
     68             lb1[ls]+=lb1[u];
     69         }
     70         else{
     71 //            LL t=max(0LL,lb1[ls]+hlb2[u]-hlb1[ls]);
     72             hlb1[ls]=max(hlb1[ls],lb1[ls]+hlb2[u]);
     73             mxB[ls]=max(mxB[ls],mxA[ls]+hlb2[u]);
     74             mxA[ls]+=lb2[u];
     75             sm[ls]+=cnt[ls]*lb2[u];
     76             lb1[ls]+=lb2[u];
     77         }
     78         hlb2[ls]=max(hlb2[ls],lb2[ls]+hlb2[u]);
     79         semx[ls]+=lb2[u];
     80         sm[ls]+=(mid-l+1-cnt[ls])*lb2[u];
     81         lb2[ls]+=lb2[u];
     82         
     83         if(mxA[rs]==lmx){
     84 //            LL t=max(0LL,lb1[rs]+hlb1[u]-hlb1[rs]);
     85             hlb1[rs]=max(hlb1[rs],lb1[rs]+hlb1[u]);
     86             mxB[rs]=max(mxB[rs],mxA[rs]+hlb1[u]);
     87             mxA[rs]+=lb1[u];
     88             sm[rs]+=cnt[rs]*lb1[u];
     89             lb1[rs]+=lb1[u];
     90         }
     91         else{
     92 //            LL t=max(0LL,lb1[rs]+hlb2[u]-hlb1[rs]);
     93             hlb1[rs]=max(hlb1[rs],lb1[rs]+hlb2[u]);
     94             mxB[rs]=max(mxB[rs],mxA[rs]+hlb2[u]);
     95             mxA[rs]+=lb2[u];
     96             sm[rs]+=cnt[rs]*lb2[u];
     97             lb1[rs]+=lb2[u];
     98         }
     99         hlb2[rs]=max(hlb2[rs],lb2[rs]+hlb2[u]);
    100         semx[rs]+=lb2[u];
    101         sm[rs]+=(r-mid-cnt[rs])*lb2[u];
    102         lb2[rs]+=lb2[u];
    103         
    104         hlb1[u]=hlb2[u]=lb1[u]=lb2[u]=0;
    105         return up(u),void();
    106     }
    107     inline void build(int u,int l,int r){
    108         hlb1[u]=hlb2[u]=lb1[u]=lb2[u]=0;
    109         semx[u]=mxA[u]=mxB[u]=-INF;
    110         cnt[u]=0;sm[u]=0;
    111         if(l==r)return mxB[u]=mxA[u]=sm[u]=kd,cnt[u]=1,void();
    112         int mid=l+r>>1;
    113         build(ls,l,mid),build(rs,mid+1,r);
    114         return up(u),void();
    115     }
    116     inline void modify_j(int u,int l,int r,int x,int y,const LL &w){
    117         down(u,l,r);
    118         if(l>=x&&r<=y){
    119             lb1[u]=w;
    120             lb2[u]=w;
    121             hlb1[u]=w;
    122             hlb2[u]=w;
    123             mxA[u]+=w;
    124             semx[u]+=w;
    125             sm[u]+=w*(r-l+1);
    126             mxB[u]=max(mxA[u],mxB[u]);
    127             return ;
    128         }
    129         int mid=l+r>>1;
    130         if(x<=mid)modify_j(ls,l,mid,x,y,w);
    131         if(y>=mid+1)modify_j(rs,mid+1,r,x,y,w);
    132         return up(u),void();
    133     }
    134     inline void modify_mn(int u,int l,int r,int x,int y,const LL &w){
    135         down(u,l,r);
    136         if(mxA[u]<=w)return ;
    137         if(l>=x&&r<=y&&w>semx[u]){
    138             sm[u]=sm[u]-cnt[u]*(mxA[u]-w);
    139             lb1[u]=w-mxA[u];
    140             mxA[u]=w;
    141             mxB[u]=max(mxA[u],mxB[u]);
    142             return ;
    143         }
    144         int mid=l+r>>1;
    145         if(x<=mid)modify_mn(ls,l,mid,x,y,w);
    146         if(y>=mid+1)modify_mn(rs,mid+1,r,x,y,w);
    147         return up(u),void();
    148     }
    149     inline LL query_mxA(int u,int l,int r,int x,int y){
    150         down(u,l,r);
    151         if(l>=x&&r<=y)return mxA[u];
    152         int mid=l+r>>1;LL res=-INF;
    153         if(x<=mid)res=max(res,query_mxA(ls,l,mid,x,y));
    154         if(y>=mid+1)res=max(res,query_mxA(rs,mid+1,r,x,y));
    155         up(u);
    156         return res;
    157     }
    158     inline LL query_mxB(int u,int l,int r,int x,int y){
    159         down(u,l,r);
    160         if(l>=x&&r<=y)return mxB[u];
    161         int mid=l+r>>1;LL res=-INF;
    162         if(x<=mid)res=max(res,query_mxB(ls,l,mid,x,y));
    163         if(y>=mid+1)res=max(res,query_mxB(rs,mid+1,r,x,y));
    164         up(u);
    165         return res;
    166     }
    167     inline LL query_sm(int u,int l,int r,int x,int y){
    168         down(u,l,r);
    169         if(l>=x&&r<=y)return sm[u];
    170         int mid=l+r>>1;LL res=0;
    171         if(x<=mid)res+=query_sm(ls,l,mid,x,y);
    172         if(y>=mid+1)res+=query_sm(rs,mid+1,r,x,y);
    173         up(u);
    174         return res;
    175     }
    176 }T;
    177 int main(){
    178 //    freopen("data.in","r",stdin);
    179 //    freopen("std.out","w",stdout);
    180     n=kd,m=kd;
    181     T.build(1,1,n);
    182     for(int i=1,op,l,r,k;i<=m;++i){
    183         op=kd,l=kd,r=kd;
    184         if(op==1)k=kd,T.modify_j(1,1,n,l,r,k);
    185         else if(op==2)k=kd,T.modify_mn(1,1,n,l,r,k);
    186         else if(op==3)printf("%lld
    ",T.query_sm(1,1,n,l,r));
    187         else if(op==4)printf("%lld
    ",T.query_mxA(1,1,n,l,r));
    188         else printf("%lld
    ",T.query_mxB(1,1,n,l,r));
    189     }
    190     return 0;
    191 }
    192 /*
    193 6 6
    194 124 53 171 50 203 152 
    195 3 2 2
    196 2 6 6 167
    197 5 5 6
    198 3 5 6
    199 4 2 6
    200 5 6 6
    201 
    202 */
    View Code
  • 相关阅读:
    p div span 标签的区别 对HTMl基础进一步理解
    js 处理 ie和firefox window.frames 兼容问题(转)
    javascript Hover事件和 mouseover 事件以及mouseout事件的联系
    JavaScript程序执行顺序问题总结(转)
    【转】 document.frames()与document.frames[]的区别
    XHTML 与 HTML 之间的差异
    root 用户和 sudo 命令
    ubuntu创建、删除文件及文件夹,强制清空回收站方法
    第二代DNA测序技术
    /usr/bin/ld: final link failed: Illegal seek
  • 原文地址:https://www.cnblogs.com/2018hzoicyf/p/15404594.html
Copyright © 2011-2022 走看看