1. 程式人生 > 其它 >吉司機線段樹學習筆記

吉司機線段樹學習筆記

先放例題,複雜度不會整坑了暫時

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\n",T.query_sm(1,1,n,l,r)); 187 else if(op==4)printf("%lld\n",T.query_mxA(1,1,n,l,r)); 188 else printf("%lld\n",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