[模板]线段树
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 inline void up(int p){ 2 sum[p]=0ll+sum[p<<1]+sum[p<<1|1]; 3 maxx[p]=max(maxx[p<<1],maxx[p<<1|1]); 4 if(maxx[p<<1]==maxx[p<<1|1])num[p]=num[p<<1]+num[p<<1|1]; 5 else num[p]=(maxx[p]==maxx[p<<1]?num[p<<1]:num[p<<1|1]); 6 sec[p]=max(sec[p<<1],sec[p<<1|1]); 7 if(maxx[p<<1]!=maxx[p<<1|1])sec[p]=max(sec[p],min(maxx[p<<1],maxx[p<<1|1])); 8 } 9 inline void down(int p){ 10 if(maxx[p]<maxx[p<<1])sum[p<<1]-=1ll*(maxx[p<<1]-maxx[p])*num[p<<1],maxx[p<<1]=maxx[p]; 11 if(maxx[p]<maxx[p<<1|1])sum[p<<1|1]-=1ll*(maxx[p<<1|1]-maxx[p])*num[p<<1|1],maxx[p<<1|1]=maxx[p]; 12 } 13 void build(int p,int l,int r){ 14 cl[p]=l;cr[p]=r; 15 if(l==r){maxx[p]=sum[p]=read();sec[p]=-1;num[p]=1;return;} 16 build(p<<1,l,l+r>>1); 17 build(p<<1|1,(l+r>>1)+1,r); 18 up(p); 19 } 20 void Min(int p){ 21 if(cl[p]>=ll&&cr[p]<=rr&&k>=maxx[p])return; 22 else if(cl[p]>=ll&&cr[p]<=rr&&k>sec[p]){ 23 sum[p]-=1ll*(maxx[p]-k)*num[p],maxx[p]=maxx[p]=k; 24 return; 25 } 26 down(p); 27 if(cr[p<<1]>=ll)Min(p<<1); 28 if(cl[p<<1|1]<=rr)Min(p<<1|1); 29 up(p); 30 } 31 int Max(int p){ 32 if(cl[p]>=ll&&cr[p]<=rr)return maxx[p]; 33 down(p); 34 return max((cr[p<<1]>=ll?Max(p<<1):0),(cl[p<<1|1]<=rr?Max(p<<1|1):0)); 35 } 36 long long Sum(int p){ 37 if(cl[p]>=ll&&cr[p]<=rr)return sum[p]; 38 down(p); 39 return (cr[p<<1]>=ll?Sum(p<<1):0ll)+(cl[p<<1|1]<=rr?Sum(p<<1|1):0ll); 40 }
$Fate \ is \ Fake$