吉司机线段树学习笔记

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

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
原文地址:https://www.cnblogs.com/2018hzoicyf/p/15404594.html