// Range max; -1 marks the empty interval.structInfo{intma;Info(int_ma=-1):ma(_ma){}Infooperator+(constInfo&o)const{returnInfo(std::max(ma,o.ma));}Info&operator+=(constInfo&o){return*this=*this+o;}};
// Maximum (non-empty) subarray sumstructInfo{intsum;// sum of the whole intervalintlma;// maximum sum of a non-empty prefixintrma;// maximum sum of a non-empty suffixintma;// maximum sum of a non-empty subarrayInfo():sum(0),lma(-1e9),rma(-1e9),ma(-1e9){}Info(intx):sum(x),lma(x),rma(x),ma(x){}Info(int_s,int_l,int_r,int_m):sum(_s),lma(_l),rma(_r),ma(_m){}Infooperator+(constInfo&o)const{returnInfo(sum+o.sum,std::max(lma,sum+o.lma),std::max(rma+o.sum,o.rma),std::max(std::max(ma,o.ma),rma+o.lma));}Info&operator+=(constInfo&o){return*this=*this+o;}};
// Recursive structure, stored in heap.#define lc(x) ((x) << 1)#define rc(x) (((x) << 1) | 1)intrt,L,R;std::vector<Info>val;voidpush_up(intcr){val[cr]=val[lc(cr)]+val[rc(cr)];}// Build the tree based on info stored in vec (0-indexed).voidbuild(intcr,intll,intrr,conststd::vector<Info>&vec){if(ll==rr)return(void)(val[cr]=vec[ll-L]);intmm=ll+((rr-ll)>>1);build(lc(cr),ll,mm,vec);build(rc(cr),mm+1,rr,vec);push_up(cr);}voidbuild(intl,intr,conststd::vector<Info>&vec){rt=1,L=l,R=r;val.resize((R-L+1)<<2);build(rt,L,R,vec);}
// Recursive structure, stored in a full binary tree.#define lc(x) ch[(x)][0]#define rc(x) ch[(x)][1]intrt,id,L,R;std::vector<std::array<int,2>>ch;std::vector<Info>val;std::vector<Transform>lazy;voidpush_up(intcr){val[cr]=val[lc(cr)]+val[rc(cr)];}// Build the tree based on info stored in vec (0-indexed).voidbuild(intcr,intll,intrr,conststd::vector<Info>&vec){if(ll==rr)return(void)(val[cr]=vec[ll-L]);intmm=ll+((rr-ll)>>1);build(lc(cr)=++id,ll,mm,vec);build(rc(cr)=++id,mm+1,rr,vec);push_up(cr);}voidbuild(intl,intr,conststd::vector<Info>&vec){rt=1,id=0,L=l,R=r;intn=R-L+1;ch.resize(n<<1),val.resize(n<<1),lazy.resize(n<<1);build(rt=++id,L,R,vec);}
提示
计算区间 [𝑙,𝑟] 中点 𝑚=⌊(𝑙+𝑟)/2⌋ 时,使用 m = l + (r - l) / 2 而不是 m = (l + r) / 2 可以避免整型溢出和负数除法向零取整等问题.
// Query info at x.Infoquery(intcr,intll,intrr,intx){if(ll==rr)returnval[cr];intmm=ll+((rr-ll)>>1);if(x<=mm)returnquery(lc(cr),ll,mm,x);elsereturnquery(rc(cr),mm+1,rr,x);}Infoquery(intx){returnquery(rt,L,R,x);}
// Modify info at x to v.voidmodify(intcr,intll,intrr,intx,constInfo&v){if(ll==rr)return(void)(val[cr]=v);intmm=ll+((rr-ll)>>1);if(x<=mm)modify(lc(cr),ll,mm,x,v);elsemodify(rc(cr),mm+1,rr,x,v);push_up(cr);}voidmodify(intx,constInfo&v){modify(rt,L,R,x,v);}
// Query info in [l, r].Infoquery(intcr,intll,intrr,inttl,inttr){if(tl<=ll&&rr<=tr)returnval[cr];intmm=ll+((rr-ll)>>1);Infores;if(tl<=mm)res=query(lc(cr),ll,mm,tl,tr);if(mm<tr)res+=query(rc(cr),mm+1,rr,tl,tr);returnres;}Infoquery(intl,intr){returnquery(rt,L,R,l,r);}
// Interval length and sum of elements.structInfo{longlonglen,sum;Info(longlong_len=0,longlong_sum=0):len(_len),sum(_sum){}Infooperator+(constInfo&o)const{returnInfo(len+o.len,sum+o.sum);}Info&operator+=(constInfo&o){return*this=*this+o;}};// Range add.structTransform{longlongv;Transform(longlong_v=0):v(_v){}explicitoperatorbool()const{returnv!=0;}Transformoperator+(constTransform&o)const{returnTransform(v+o.v);}Transform&operator+=(constTransform&o){return*this=*this+o;}Infooperator()(constInfo&x)const{returnInfo(x.len,x.sum+v*x.len);}};
// Range max; -1 marks the empty interval.structInfo{intma;Info(int_ma=-1):ma(_ma){}Infooperator+(constInfo&o)const{returnInfo(std::max(ma,o.ma));}Info&operator+=(constInfo&o){return*this=*this+o;}};// Assignment; -1 marks no assignment.structTransform{intx;Transform(int_x=-1):x(_x){}explicitoperatorbool()const{returnx!=-1;}Transformoperator+(constTransform&o)const{returno?o:*this;}Transform&operator+=(constTransform&o){return*this=*this+o;}Infooperator()(constInfo&v)const{return*this&&v.ma!=-1?Info(x):v;}};
在实现好用于存储区间修改操作的结构后,懒惰更新和下传懒惰标记的操作就可以实现如下:
参考实现
1 2 3 4 5 6 7 8 910111213
// Lazy update.voidlazy_update(intcr,constTransform&f){val[cr]=f(val[cr]);lazy[cr]+=f;}// Push down lazy tag.voidpush_down(intcr){if(!lazy[cr])return;lazy_update(lc(cr),lazy[cr]);lazy_update(rc(cr),lazy[cr]);lazy[cr]=Transform();}
提示
不要将懒惰标记打到空结点上.
如果实现得仔细,也可以不将懒惰标记打到叶结点上.
单次下传操作的复杂度通常是 𝑂(1) 的.
进而,区间修改操作就可以实现如下:
参考实现
1 2 3 4 5 6 7 8 91011
// Apply transformation f to the range [l, r].voidmodify(intcr,intll,intrr,inttl,inttr,constTransform&f){if(tl<=ll&&rr<=tr)returnlazy_update(cr,f);push_down(cr);intmm=ll+((rr-ll)>>1);if(tl<=mm)modify(lc(cr),ll,mm,tl,tr,f);if(mm<tr)modify(rc(cr),mm+1,rr,tl,tr,f);push_up(cr);}voidmodify(intl,intr,constTransform&f){modify(rt,L,R,l,r,f);}
// Segment Tree Implementation. Recursive. No lazy tag.// Recursive structure, stored in heap.#define lc(x) ((x) << 1)#define rc(x) (((x) << 1) | 1)intrt,L,R;std::vector<Info>val;voidpush_up(intcr){val[cr]=val[lc(cr)]+val[rc(cr)];}// Build the tree based on info stored in vec (0-indexed).voidbuild(intcr,intll,intrr,conststd::vector<Info>&vec){if(ll==rr)return(void)(val[cr]=vec[ll-L]);intmm=ll+((rr-ll)>>1);build(lc(cr),ll,mm,vec);build(rc(cr),mm+1,rr,vec);push_up(cr);}voidbuild(intl,intr,conststd::vector<Info>&vec){rt=1,L=l,R=r;val.resize((R-L+1)<<2);build(rt,L,R,vec);}// Query info at x.Infoquery(intcr,intll,intrr,intx){if(ll==rr)returnval[cr];intmm=ll+((rr-ll)>>1);if(x<=mm)returnquery(lc(cr),ll,mm,x);elsereturnquery(rc(cr),mm+1,rr,x);}Infoquery(intx){returnquery(rt,L,R,x);}// Modify info at x to v.voidmodify(intcr,intll,intrr,intx,constInfo&v){if(ll==rr)return(void)(val[cr]=v);intmm=ll+((rr-ll)>>1);if(x<=mm)modify(lc(cr),ll,mm,x,v);elsemodify(rc(cr),mm+1,rr,x,v);push_up(cr);}voidmodify(intx,constInfo&v){modify(rt,L,R,x,v);}// Query info in [l, r].Infoquery(intcr,intll,intrr,inttl,inttr){if(tl<=ll&&rr<=tr)returnval[cr];intmm=ll+((rr-ll)>>1);Infores;if(tl<=mm)res=query(lc(cr),ll,mm,tl,tr);if(mm<tr)res+=query(rc(cr),mm+1,rr,tl,tr);returnres;}Infoquery(intl,intr){returnquery(rt,L,R,l,r);}
// Segment Tree Implementation. Recursive. With lazy tag.// Recursive structure, stored in a full binary tree.#define lc(x) ch[(x)][0]#define rc(x) ch[(x)][1]intrt,id,L,R;std::vector<std::array<int,2>>ch;std::vector<Info>val;std::vector<Transform>lazy;voidpush_up(intcr){val[cr]=val[lc(cr)]+val[rc(cr)];}// Build the tree based on info stored in vec (0-indexed).voidbuild(intcr,intll,intrr,conststd::vector<Info>&vec){if(ll==rr)return(void)(val[cr]=vec[ll-L]);intmm=ll+((rr-ll)>>1);build(lc(cr)=++id,ll,mm,vec);build(rc(cr)=++id,mm+1,rr,vec);push_up(cr);}voidbuild(intl,intr,conststd::vector<Info>&vec){rt=1,id=0,L=l,R=r;intn=R-L+1;ch.resize(n<<1),val.resize(n<<1),lazy.resize(n<<1);build(rt=++id,L,R,vec);}// Lazy update.voidlazy_update(intcr,constTransform&f){val[cr]=f(val[cr]);lazy[cr]+=f;}// Push down lazy tag.voidpush_down(intcr){if(!lazy[cr])return;lazy_update(lc(cr),lazy[cr]);lazy_update(rc(cr),lazy[cr]);lazy[cr]=Transform();}// Query info at x.Infoquery(intcr,intll,intrr,intx){if(ll==rr)returnval[cr];push_down(cr);intmm=ll+((rr-ll)>>1);if(x<=mm)returnquery(lc(cr),ll,mm,x);elsereturnquery(rc(cr),mm+1,rr,x);}Infoquery(intx){returnquery(rt,L,R,x);}// Apply transformation f to the value at x.voidmodify(intcr,intll,intrr,intx,constTransform&f){if(ll==rr)return(void)(val[cr]=f(val[cr]));push_down(cr);intmm=ll+((rr-ll)>>1);if(x<=mm)modify(lc(cr),ll,mm,x,f);elsemodify(rc(cr),mm+1,rr,x,f);push_up(cr);}voidmodify(intx,constTransform&f){modify(rt,L,R,x,f);}// Query info in [l, r].Infoquery(intcr,intll,intrr,inttl,inttr){if(tl<=ll&&rr<=tr)returnval[cr];push_down(cr);intmm=ll+((rr-ll)>>1);Infores;if(tl<=mm)res=query(lc(cr),ll,mm,tl,tr);if(mm<tr)res+=query(rc(cr),mm+1,rr,tl,tr);returnres;}Infoquery(intl,intr){returnquery(rt,L,R,l,r);}// Apply transformation f to the range [l, r].voidmodify(intcr,intll,intrr,inttl,inttr,constTransform&f){if(tl<=ll&&rr<=tr)returnlazy_update(cr,f);push_down(cr);intmm=ll+((rr-ll)>>1);if(tl<=mm)modify(lc(cr),ll,mm,tl,tr,f);if(mm<tr)modify(rc(cr),mm+1,rr,tl,tr,f);push_up(cr);}voidmodify(intl,intr,constTransform&f){modify(rt,L,R,l,r,f);}
// Nonrecursive structure, embedded in a perfect binary tree.intn,L,R;std::vector<Info>val;voidpush_up(intcr){val[cr]=val[cr<<1]+val[(cr<<1)|1];}// Build the tree based on info stored in vec (0-indexed).voidbuild(intl,intr,conststd::vector<Info>&vec){L=l,R=r;for(n=1;n<r-l+1;n<<=1);val.resize(n<<1);std::copy(vec.begin(),vec.end(),val.begin()+n);for(inti=n-1;i;--i)push_up(i);}// Query info at x.Infoquery(intx){returnval[n+x-L];}// Modify info at x to v.voidmodify(intx,constInfo&v){x=x-L+n;val[x]=v;for(x>>=1;x;x>>=1)push_up(x);}
// Apply transformation f to the range [l, r].voidmodify(intl,intr,constTransform&f){l=l-L+n,r=r-L+n;for(inti=h,m=(1<<h)-1;i;--i,m>>=1){if(l&m)push_down(l>>i);if(~r&m)push_down(r>>i);}for(intll=l,rr=r;ll<=rr;ll>>=1,rr>>=1){if(ll&1)lazy_update(ll++,f);if(~rr&1)lazy_update(rr--,f);}for(inti=1,m=1;i<=h;++i,m=(m<<1)|1){if(l&m)push_up(l>>i);if(~r&m)push_up(r>>i);}}
// Segment Tree Implementation. Nonrecursive. No lazy tag.// Nonrecursive structure, embedded in a perfect binary tree.intn,L,R;std::vector<Info>val;voidpush_up(intcr){val[cr]=val[cr<<1]+val[(cr<<1)|1];}// Build the tree based on info stored in vec (0-indexed).voidbuild(intl,intr,conststd::vector<Info>&vec){L=l,R=r;for(n=1;n<r-l+1;n<<=1);val.resize(n<<1);std::copy(vec.begin(),vec.end(),val.begin()+n);for(inti=n-1;i;--i)push_up(i);}// Query info at x.Infoquery(intx){returnval[n+x-L];}// Modify info at x to v.voidmodify(intx,constInfo&v){x=x-L+n;val[x]=v;for(x>>=1;x;x>>=1)push_up(x);}// Query info in [l, r].Infoquery(intl,intr){Infola,ra;for(l=l-L+n,r=r-L+n;l<=r;l>>=1,r>>=1){if(l&1)la+=val[l++];if(~r&1)ra=val[r--]+ra;}returnla+ra;}
// Segment Tree Implementation. Nonrecursive. With lazy tag.// Nonrecursive structure, embedded in a perfect binary tree.intn,h,L,R;std::vector<Info>val;std::vector<Transform>lazy;voidpush_up(intcr){val[cr]=val[cr<<1]+val[(cr<<1)|1];}// Build the tree based on info stored in vec (0-indexed).voidbuild(intl,intr,conststd::vector<Info>&vec){L=l,R=r,n=r-l+1;for(h=0;(1<<h)<n;++h);n=1<<h;val.resize(n<<1),lazy.resize(n);std::copy(vec.begin(),vec.end(),val.begin()+n);for(inti=n-1;i;--i)push_up(i);}// Lazy update.voidlazy_update(intcr,constTransform&f){val[cr]=f(val[cr]);if(cr<n)lazy[cr]+=f;}// Push down lazy tag.voidpush_down(intcr){if(!lazy[cr])return;lazy_update(cr<<1,lazy[cr]);lazy_update((cr<<1)|1,lazy[cr]);lazy[cr]=Transform();}// Query info at x.Infoquery(intx){x=x-L+n;for(inti=h;i;--i)push_down(x>>i);returnval[x];}// Apply transformation f to the value at x.voidmodify(intx,constTransform&f){x=x-L+n;for(inti=h;i;--i)push_down(x>>i);val[x]=f(val[x]);for(inti=1;i<=h;++i)push_up(x>>i);}// Query info in [l, r].Infoquery(intl,intr){l=l-L+n,r=r-L+n;for(inti=h,m=(1<<h)-1;i;--i,m>>=1){if(l&m)push_down(l>>i);if(~r&m)push_down(r>>i);}Infola,ra;for(;l<=r;l>>=1,r>>=1){if(l&1)la+=val[l++];if(~r&1)ra=val[r--]+ra;}returnla+ra;}// Apply transformation f to the range [l, r].voidmodify(intl,intr,constTransform&f){l=l-L+n,r=r-L+n;for(inti=h,m=(1<<h)-1;i;--i,m>>=1){if(l&m)push_down(l>>i);if(~r&m)push_down(r>>i);}for(intll=l,rr=r;ll<=rr;ll>>=1,rr>>=1){if(ll&1)lazy_update(ll++,f);if(~rr&1)lazy_update(rr--,f);}for(inti=1,m=1;i<=h;++i,m=(m<<1)|1){if(l&m)push_up(l>>i);if(~r&m)push_up(r>>i);}}
// Segment Tree Implementation. Dynamic node allocation.// Dynamic node allocation.#define lc(x) ch[(x)][0]#define rc(x) ch[(x)][1]intrt,id,L,R;std::vector<std::array<int,2>>ch;std::vector<Info>val;voidpush_up(intcr){val[cr]=val[lc(cr)]+val[rc(cr)];}// Build an empty tree.voidbuild(intl,intr,intn){rt=0,id=0,L=l,R=r;ch.resize(n),val.resize(n);}// Query info at x.Infoquery(intcr,intll,intrr,intx){if(!cr)return{};if(ll==rr)returnval[cr];intmm=ll+((rr-ll)>>1);if(x<=mm)returnquery(lc(cr),ll,mm,x);elsereturnquery(rc(cr),mm+1,rr,x);}Infoquery(intx){returnquery(rt,L,R,x);}// Modify info at x to v.voidmodify(int&cr,intll,intrr,intx,constInfo&v){if(!cr)cr=++id;if(ll==rr)return(void)(val[cr]=v);intmm=ll+((rr-ll)>>1);if(x<=mm)modify(lc(cr),ll,mm,x,v);elsemodify(rc(cr),mm+1,rr,x,v);push_up(cr);}voidmodify(intx,constInfo&v){modify(rt,L,R,x,v);}// Query info in [l, r].Infoquery(intcr,intll,intrr,inttl,inttr){if(!cr)return{};if(tl<=ll&&rr<=tr)returnval[cr];intmm=ll+((rr-ll)>>1);Infores;if(tl<=mm)res=query(lc(cr),ll,mm,tl,tr);if(mm<tr)res+=query(rc(cr),mm+1,rr,tl,tr);returnres;}Infoquery(intl,intr){returnquery(rt,L,R,l,r);}
// Segment Tree Implementation. Dynamic node allocation.// Recursive structure, stored in a full binary tree.#define lc(x) ch[(x)][0]#define rc(x) ch[(x)][1]intrt,id,L,R;std::vector<std::array<int,2>>ch;std::vector<Info>val;std::vector<Transform>lazy;Infoblank(intll,intrr);// Info of untouched node; problem-specific.Infoinfo_of(intcr,intll,intrr){returncr?val[cr]:blank(ll,rr);}voidpush_up(intcr,intll,intrr){intmm=ll+((rr-ll)>>1);val[cr]=info_of(lc(cr),ll,mm)+info_of(rc(cr),mm+1,rr);}// Build an empty tree.voidbuild(intl,intr,intn){rt=0,id=0,L=l,R=r;ch.resize(n),val.resize(n),lazy.resize(n);}// Lazy update.voidlazy_update(int&cr,intll,intrr,constTransform&f){if(!cr)val[cr=++id]=blank(ll,rr);val[cr]=f(val[cr]);lazy[cr]+=f;}// Push down lazy tag.voidpush_down(intcr,intll,intrr){if(!lazy[cr])return;intmm=ll+((rr-ll)>>1);lazy_update(lc(cr),ll,mm,lazy[cr]);lazy_update(rc(cr),mm+1,rr,lazy[cr]);lazy[cr]=Transform();}// Query info at x.Infoquery(intcr,intll,intrr,intx){if(!cr)returnblank(ll,rr);if(ll==rr)returnval[cr];push_down(cr,ll,rr);intmm=ll+((rr-ll)>>1);if(x<=mm)returnquery(lc(cr),ll,mm,x);elsereturnquery(rc(cr),mm+1,rr,x);}Infoquery(intx){returnquery(rt,L,R,x);}// Apply transformation f to the value at x.voidmodify(int&cr,intll,intrr,intx,constTransform&f){if(!cr)val[cr=++id]=blank(ll,rr);if(ll==rr)return(void)(val[cr]=f(val[cr]));push_down(cr,ll,rr);intmm=ll+((rr-ll)>>1);if(x<=mm)modify(lc(cr),ll,mm,x,f);elsemodify(rc(cr),mm+1,rr,x,f);push_up(cr,ll,rr);}voidmodify(intx,constTransform&f){modify(rt,L,R,x,f);}// Query info in [l, r].Infoquery(intcr,intll,intrr,inttl,inttr){if(!cr)returnblank(std::max(ll,tl),std::min(rr,tr));if(tl<=ll&&rr<=tr)returnval[cr];push_down(cr,ll,rr);intmm=ll+((rr-ll)>>1);Infores;if(tl<=mm)res=query(lc(cr),ll,mm,tl,tr);if(mm<tr)res+=query(rc(cr),mm+1,rr,tl,tr);returnres;}Infoquery(intl,intr){returnquery(rt,L,R,l,r);}// Apply transformation f to the range [l, r].voidmodify(int&cr,intll,intrr,inttl,inttr,constTransform&f){if(!cr)val[cr=++id]=blank(ll,rr);if(tl<=ll&&rr<=tr)returnlazy_update(cr,ll,rr,f);push_down(cr,ll,rr);intmm=ll+((rr-ll)>>1);if(tl<=mm)modify(lc(cr),ll,mm,tl,tr,f);if(mm<tr)modify(rc(cr),mm+1,rr,tl,tr,f);push_up(cr,ll,rr);}voidmodify(intl,intr,constTransform&f){modify(rt,L,R,l,r,f);}
// Segment Tree Implementation. Recursive. With lazy tag.// Recursive structure, stored in a full binary tree.#define lc(x) ch[(x)][0]#define rc(x) ch[(x)][1]intrt,id,L,R;std::vector<std::array<int,2>>ch;std::vector<Info>val;std::vector<Transform>lazy;voidpush_up(intcr){val[cr]=lazy[cr](val[lc(cr)]+val[rc(cr)]);}// Build the tree based on info stored in vec (0-indexed).voidbuild(intcr,intll,intrr,conststd::vector<Info>&vec){if(ll==rr)return(void)(val[cr]=vec[ll-L]);intmm=ll+((rr-ll)>>1);build(lc(cr)=++id,ll,mm,vec);build(rc(cr)=++id,mm+1,rr,vec);push_up(cr);}voidbuild(intl,intr,conststd::vector<Info>&vec){rt=1,id=0,L=l,R=r;intn=R-L+1;ch.resize(n<<1),val.resize(n<<1),lazy.resize(n<<1);build(rt=++id,L,R,vec);}// Lazy update.voidlazy_update(intcr,constTransform&f){val[cr]=f(val[cr]);lazy[cr]+=f;}// Query info at x.Infoquery(intcr,intll,intrr,intx){if(ll==rr)returnval[cr];intmm=ll+((rr-ll)>>1);returnlazy[cr](x<=mm?query(lc(cr),ll,mm,x):query(rc(cr),mm+1,rr,x));}Infoquery(intx){returnquery(rt,L,R,x);}// Apply transformation f to the value at x.voidmodify(intcr,intll,intrr,intx,constTransform&f){if(ll==rr)return(void)(val[cr]=f(val[cr]));intmm=ll+((rr-ll)>>1);if(x<=mm)modify(lc(cr),ll,mm,x,f);elsemodify(rc(cr),mm+1,rr,x,f);push_up(cr);}voidmodify(intx,constTransform&f){modify(rt,L,R,x,f);}// Query info in [l, r].Infoquery(intcr,intll,intrr,inttl,inttr){if(tl<=ll&&rr<=tr)returnval[cr];intmm=ll+((rr-ll)>>1);Infores;if(tl<=mm)res=query(lc(cr),ll,mm,tl,tr);if(mm<tr)res+=query(rc(cr),mm+1,rr,tl,tr);returnlazy[cr](res);}Infoquery(intl,intr){returnquery(rt,L,R,l,r);}// Apply transformation f to the range [l, r].voidmodify(intcr,intll,intrr,inttl,inttr,constTransform&f){if(tl<=ll&&rr<=tr)returnlazy_update(cr,f);intmm=ll+((rr-ll)>>1);if(tl<=mm)modify(lc(cr),ll,mm,tl,tr,f);if(mm<tr)modify(rc(cr),mm+1,rr,tl,tr,f);push_up(cr);}voidmodify(intl,intr,constTransform&f){modify(rt,L,R,l,r,f);}
// Segment Tree Implementation. Nonrecursive. With lazy tag.// Nonrecursive structure, embedded in a perfect binary tree.intn,h,L,R;std::vector<Info>val;std::vector<Transform>lazy;voidpush_up(intcr){val[cr]=lazy[cr](val[cr<<1]+val[(cr<<1)|1]);}// Build the tree based on info stored in vec (0-indexed).voidbuild(intl,intr,conststd::vector<Info>&vec){L=l,R=r,n=r-l+1;for(h=0;(1<<h)<n;++h);n=1<<h;val.resize(n<<1),lazy.resize(n);std::copy(vec.begin(),vec.end(),val.begin()+n);for(inti=n-1;i;--i)push_up(i);}// Lazy update.voidlazy_update(intcr,constTransform&f){val[cr]=f(val[cr]);if(cr<n)lazy[cr]+=f;}// Query info at x.Infoquery(intx){x=x-L+n;autores=val[x];for(inti=1;i<=h;++i)res=lazy[x>>i](res);returnres;}// Apply transformation f to the value at x.voidmodify(intx,constTransform&f){x=x-L+n;val[x]=f(val[x]);for(inti=1;i<=h;++i)push_up(x>>i);}// Query info in [l, r].Infoquery(intl,intr){l=l-L+n,r=r-L+n;Infola,ra;for(inti=0,ll=l,rr=r;i<=h;++i){if(i)la=lazy[l>>i](la),ra=lazy[r>>i](ra);if(ll<=rr){if(ll&1)la+=val[ll++];if(~rr&1)ra=val[rr--]+ra;ll>>=1,rr>>=1;}}returnla+ra;}// Apply transformation f to the range [l, r].voidmodify(intl,intr,constTransform&f){l=l-L+n,r=r-L+n;for(intll=l,rr=r;ll<=rr;ll>>=1,rr>>=1){if(ll&1)lazy_update(ll++,f);if(~rr&1)lazy_update(rr--,f);}for(inti=1,m=1;i<=h;++i,m=(m<<1)|1){if(l&m)push_up(l>>i);if(~r&m)push_up(r>>i);}}
// Find max r in [l, R] such that g(info([l, r])) is true.// Return l - 1 if no such r exists.template<typenameG>intmax_right(intcr,intll,intrr,inttl,constG&g,Info&acc){if(tl<=ll){autonxt=acc+val[cr];if(g(nxt))returnacc=nxt,rr;if(ll==rr)returnll-1;}push_down(cr);intmm=ll+((rr-ll)>>1);if(tl<=mm){autores=max_right(lc(cr),ll,mm,tl,g,acc);if(res<mm)returnres;}returnmax_right(rc(cr),mm+1,rr,tl,g,acc);}template<typenameG>intmax_right(intl,constG&g){Infoacc;returnmax_right(rt,L,R,l,g,acc);}// Find min l in [L, r] such that g(info([l, r])) is true.// Return r + 1 if no such l exists.template<typenameG>intmin_left(intcr,intll,intrr,inttr,constG&g,Info&acc){if(tr>=rr){autonxt=val[cr]+acc;if(g(nxt))returnacc=nxt,ll;if(ll==rr)returnrr+1;}push_down(cr);intmm=ll+((rr-ll)>>1);if(tr>mm){autores=min_left(rc(cr),mm+1,rr,tr,g,acc);if(res>mm+1)returnres;}returnmin_left(lc(cr),ll,mm,tr,g,acc);}template<typenameG>intmin_left(intr,constG&g){Infoacc;returnmin_left(rt,L,R,r,g,acc);}
// Find max r in [l, R] such that g(info([l, r])) is true.// Return l - 1 if no such r exists.template<typenameG>intmax_right(intl,constG&g){l=l-L+n;for(inti=h;i;--i)push_down(l>>i);Infoacc;for(;;){while(~l&1)l>>=1;autonxt=acc+val[l];if(!g(nxt)){while(l<n){push_down(l);l<<=1;nxt=acc+val[l];if(g(nxt))acc=nxt,++l;}returnl-n+L-1;}acc=nxt,++l;if((l&-l)==l)break;}returnR;}// Find min l in [L, r] such that g(info([l, r])) is true.// Return r + 1 if no such l exists.template<typenameG>intmin_left(intr,constG&g){r=r-L+n;for(inti=h;i;--i)push_down(r>>i);Infoacc;for(;;){while((r&1)&&(r^1))r>>=1;autonxt=val[r]+acc;if(!g(nxt)){while(r<n){push_down(r);r=(r<<1)|1;nxt=val[r]+acc;if(g(nxt))acc=nxt,--r;}returnr-n+L+1;}if((r&-r)==r)break;acc=nxt,--r;}returnL;}
// Segment tree on values, supporting the ordered-set operations of a BST.intrt,id,L,R;std::vector<int>lc,rc;std::vector<int>cnt;voidbuild(intl,intr,intn){rt=0,id=0,L=l,R=r;lc.resize(n),rc.resize(n),cnt.resize(n);}// Insert v.voidinsert(int&cr,intll,intrr,intv){if(!cr)cr=++id;++cnt[cr];if(ll==rr)return;intmm=ll+((rr-ll)>>1);if(v<=mm)insert(lc[cr],ll,mm,v);elseinsert(rc[cr],mm+1,rr,v);}voidinsert(intv){insert(rt,L,R,v);}// Remove v.// If there are multiple, remove once.// Return true if there is any, return false if there is none.boolremove(intcr,intll,intrr,intv){if(!cnt[cr])returnfalse;if(ll==rr)returncnt[cr]--;intmm=ll+((rr-ll)>>1);autosucc=false;if(v<=mm)succ=remove(lc[cr],ll,mm,v);elsesucc=remove(rc[cr],mm+1,rr,v);returnsucc&&cnt[cr]--;}boolremove(intv){returnremove(rt,L,R,v);}// Count values within range [l, r].intcount(intcr,intll,intrr,inttl,inttr){if(!cr)return0;if(tl<=ll&&rr<=tr)returncnt[cr];intmm=ll+((rr-ll)>>1);intres=0;if(tl<=mm)res=count(lc[cr],ll,mm,tl,tr);if(mm<tr)res+=count(rc[cr],mm+1,rr,tl,tr);returnres;}intcount(intl,intr){returncount(rt,L,R,l,r);}// Find the rank of v, i.e., one plus the count of numbers less than v.intfind_rank(intv){returnv>L?count(L,v-1)+1:1;}// Find the k-th element.intfind_kth(intcr,intll,intrr,intk){if(ll==rr)returnll;intmm=ll+((rr-ll)>>1);if(k<=cnt[lc[cr]])returnfind_kth(lc[cr],ll,mm,k);elsereturnfind_kth(rc[cr],mm+1,rr,k-cnt[lc[cr]]);}intfind_kth(intk){returnk>cnt[rt]||k<=0?-1:find_kth(rt,L,R,k);}// Find the predecessor of v.intfind_prev(intx){returnfind_kth(find_rank(x)-1);}// Find the successor of v.intfind_next(intx){returnfind_kth(find_rank(x+1));}
#include<algorithm>#include<array>#include<iostream>#include<vector>// Interval length and sum of elements.structInfo{longlonglen,sum;Info(longlong_len=0,longlong_sum=0):len(_len),sum(_sum){}Infooperator+(constInfo&o)const{returnInfo(len+o.len,sum+o.sum);}Info&operator+=(constInfo&o){return*this=*this+o;}};// Range add.structTransform{longlongv;Transform(longlong_v=0):v(_v){}explicitoperatorbool()const{returnv!=0;}Transformoperator+(constTransform&o)const{returnTransform(v+o.v);}Transform&operator+=(constTransform&o){return*this=*this+o;}Infooperator()(constInfo&x)const{returnInfo(x.len,x.sum+v*x.len);}};// Segment Tree.// Recursive structure, stored in a full binary tree.#define lc(x) ch[(x)][0]#define rc(x) ch[(x)][1]intrt,id,L,R;std::vector<std::array<int,2>>ch;std::vector<Info>val;std::vector<Transform>lazy;voidpush_up(intcr){val[cr]=val[lc(cr)]+val[rc(cr)];}// Build the tree based on info stored in vec (0-indexed).voidbuild(intcr,intll,intrr,conststd::vector<Info>&vec){if(ll==rr)return(void)(val[cr]=vec[ll-L]);intmm=ll+((rr-ll)>>1);build(lc(cr)=++id,ll,mm,vec);build(rc(cr)=++id,mm+1,rr,vec);push_up(cr);}voidbuild(intl,intr,conststd::vector<Info>&vec){rt=1,id=0,L=l,R=r;intn=R-L+1;ch.resize(n<<1),val.resize(n<<1),lazy.resize(n<<1);build(rt=++id,L,R,vec);}// Lazy update.voidlazy_update(intcr,constTransform&f){val[cr]=f(val[cr]);lazy[cr]+=f;}// Push down lazy tag.voidpush_down(intcr){if(!lazy[cr])return;lazy_update(lc(cr),lazy[cr]);lazy_update(rc(cr),lazy[cr]);lazy[cr]=Transform();}// Query info in [l, r].Infoquery(intcr,intll,intrr,inttl,inttr){if(tl<=ll&&rr<=tr)returnval[cr];push_down(cr);intmm=ll+((rr-ll)>>1);Infores;if(tl<=mm)res=query(lc(cr),ll,mm,tl,tr);if(mm<tr)res+=query(rc(cr),mm+1,rr,tl,tr);returnres;}Infoquery(intl,intr){returnquery(rt,L,R,l,r);}// Apply transformation f to the range [l, r].voidmodify(intcr,intll,intrr,inttl,inttr,constTransform&f){if(tl<=ll&&rr<=tr)returnlazy_update(cr,f);push_down(cr);intmm=ll+((rr-ll)>>1);if(tl<=mm)modify(lc(cr),ll,mm,tl,tr,f);if(mm<tr)modify(rc(cr),mm+1,rr,tl,tr,f);push_up(cr);}voidmodify(intl,intr,constTransform&f){modify(rt,L,R,l,r,f);}intmain(){std::ios::sync_with_stdio(false),std::cin.tie(nullptr);intn,m;std::cin>>n>>m;std::vector<Info>vec(n);for(auto&v:vec){longlongx;std::cin>>x;v=Info(1,x);}build(1,n,vec);for(;m;--m){intop;std::cin>>op;if(op==1){intx,y;longlongk;std::cin>>x>>y>>k;modify(x,y,Transform(k));}elseif(op==2){intx,y;std::cin>>x>>y;std::cout<<query(x,y).sum<<'\n';}}return0;}
#include<algorithm>#include<array>#include<iostream>#include<vector>intM;// Interval length and sum of elements.structInfo{intlen,sum;Info(int_len=0,int_sum=0):len(_len),sum(_sum){}Infooperator+(constInfo&o)const{returnInfo(len+o.len,(sum+o.sum)%M);}Info&operator+=(constInfo&o){return*this=*this+o;}};// Affine transformation.structTransform{inta,b;Transform(int_a=1,int_b=0):a(_a),b(_b){}explicitoperatorbool()const{returna!=1||b!=0;}Transformoperator+(constTransform&o)const{returnTransform((longlong)o.a*a%M,((longlong)o.a*b+o.b)%M);}Transform&operator+=(constTransform&o){return*this=*this+o;}Infooperator()(constInfo&x)const{returnInfo(x.len,((longlong)a*x.sum+(longlong)b*x.len)%M);}};// Segment Tree.// Recursive structure, stored in a full binary tree.#define lc(x) ch[(x)][0]#define rc(x) ch[(x)][1]intrt,id,L,R;std::vector<std::array<int,2>>ch;std::vector<Info>val;std::vector<Transform>lazy;voidpush_up(intcr){val[cr]=val[lc(cr)]+val[rc(cr)];}// Build the tree based on info stored in vec (0-indexed).voidbuild(intcr,intll,intrr,conststd::vector<Info>&vec){if(ll==rr)return(void)(val[cr]=vec[ll-L]);intmm=ll+((rr-ll)>>1);build(lc(cr)=++id,ll,mm,vec);build(rc(cr)=++id,mm+1,rr,vec);push_up(cr);}voidbuild(intl,intr,conststd::vector<Info>&vec){rt=1,id=0,L=l,R=r;intn=R-L+1;ch.resize(n<<1),val.resize(n<<1),lazy.resize(n<<1);build(rt=++id,L,R,vec);}// Lazy update.voidlazy_update(intcr,constTransform&f){val[cr]=f(val[cr]);lazy[cr]+=f;}// Push down lazy tag.voidpush_down(intcr){if(!lazy[cr])return;lazy_update(lc(cr),lazy[cr]);lazy_update(rc(cr),lazy[cr]);lazy[cr]=Transform();}// Query info in [l, r].Infoquery(intcr,intll,intrr,inttl,inttr){if(tl<=ll&&rr<=tr)returnval[cr];push_down(cr);intmm=ll+((rr-ll)>>1);Infores;if(tl<=mm)res=query(lc(cr),ll,mm,tl,tr);if(mm<tr)res+=query(rc(cr),mm+1,rr,tl,tr);returnres;}Infoquery(intl,intr){returnquery(rt,L,R,l,r);}// Apply transformation f to the range [l, r].voidmodify(intcr,intll,intrr,inttl,inttr,constTransform&f){if(tl<=ll&&rr<=tr)returnlazy_update(cr,f);push_down(cr);intmm=ll+((rr-ll)>>1);if(tl<=mm)modify(lc(cr),ll,mm,tl,tr,f);if(mm<tr)modify(rc(cr),mm+1,rr,tl,tr,f);push_up(cr);}voidmodify(intl,intr,constTransform&f){modify(rt,L,R,l,r,f);}intmain(){std::ios::sync_with_stdio(false),std::cin.tie(nullptr);intn,q;std::cin>>n>>q>>M;std::vector<Info>vec(n);for(auto&v:vec){longlongx;std::cin>>x;v=Info(1,x);}build(1,n,vec);for(;q;--q){intop;std::cin>>op;if(op==1){intx,y,k;std::cin>>x>>y>>k;modify(x,y,Transform(k,0));}elseif(op==2){intx,y,k;std::cin>>x>>y>>k;modify(x,y,Transform(1,k));}elseif(op==3){intx,y;std::cin>>x>>y;std::cout<<query(x,y).sum<<'\n';}}return0;}
#include<algorithm>#include<iostream>#include<vector>// Maximum (non-empty) subarray sumstructInfo{intsum;// sum of the whole intervalintlma;// maximum sum of a non-empty prefixintrma;// maximum sum of a non-empty suffixintma;// maximum sum of a non-empty subarrayInfo():sum(0),lma(-1e9),rma(-1e9),ma(-1e9){}Info(intx):sum(x),lma(x),rma(x),ma(x){}Info(int_s,int_l,int_r,int_m):sum(_s),lma(_l),rma(_r),ma(_m){}Infooperator+(constInfo&o)const{returnInfo(sum+o.sum,std::max(lma,sum+o.lma),std::max(rma+o.sum,o.rma),std::max(std::max(ma,o.ma),rma+o.lma));}Info&operator+=(constInfo&o){return*this=*this+o;}};// Segment tree.classSegmentTree{intrt,id,L,R;std::vector<int>lc,rc;std::vector<Info>val;voidpush_up(intcr){val[cr]=val[lc[cr]]+val[rc[cr]];}voidbuild(intcr,intll,intrr,conststd::vector<int>&vec){if(ll==rr)return(void)(val[cr]=Info(vec[ll-L]));intmm=ll+((rr-ll)>>1);build(lc[cr]=++id,ll,mm,vec);build(rc[cr]=++id,mm+1,rr,vec);push_up(cr);}voidmodify(intcr,intll,intrr,intx,intv){if(ll==rr)return(void)(val[cr]=Info(v));intmm=ll+((rr-ll)>>1);if(x<=mm)modify(lc[cr],ll,mm,x,v);elsemodify(rc[cr],mm+1,rr,x,v);push_up(cr);}Infoquery(intcr,intll,intrr,inttl,inttr){if(tl<=ll&&rr<=tr)returnval[cr];intmm=ll+((rr-ll)>>1);Infores;if(tl<=mm)res=query(lc[cr],ll,mm,tl,tr);if(mm<tr)res+=query(rc[cr],mm+1,rr,tl,tr);returnres;}public:SegmentTree(intn,conststd::vector<int>&vec):rt(0),id(0),L(1),R(n),lc(n<<1),rc(n<<1),val(n<<1){build(rt=++id,L,R,vec);}voidmodify(intx,intv){modify(rt,L,R,x,v);}Infoquery(intl,intr){returnquery(rt,L,R,l,r);}};intmain(){std::ios::sync_with_stdio(false),std::cin.tie(nullptr);intn;std::cin>>n;std::vector<int>vec(n);for(auto&x:vec)std::cin>>x;SegmentTreeseg(n,vec);intm;std::cin>>m;for(;m;--m){intop;std::cin>>op;if(op==0){intx,y;std::cin>>x>>y;seg.modify(x,y);}elseif(op==1){intl,r;std::cin>>l>>r;std::cout<<seg.query(l,r).ma<<'\n';}}return0;}
#include<algorithm>#include<array>#include<iostream>#include<vector>usingu64=unsignedlonglong;// Interval length and sum of elements.structInfo{u64len,sum;Info(u64_len=0,u64_sum=0):len(_len),sum(_sum){}Infooperator+(constInfo&o)const{returnInfo(len+o.len,sum+o.sum);}Info&operator+=(constInfo&o){return*this=*this+o;}};// Range add.structTransform{u64a;Transform(u64_a=0):a(_a){}explicitoperatorbool()const{returna!=0;}Transformoperator+(constTransform&o)const{returnTransform(a+o.a);}Transform&operator+=(constTransform&o){return*this=*this+o;}Infooperator()(constInfo&v)const{returnInfo(v.len,v.sum+a*v.len);}};// Segment Tree Implementation. Dynamic node allocation.// Recursive structure, stored in a full binary tree.#define lc(x) ch[(x)][0]#define rc(x) ch[(x)][1]intrt,id,L,R;std::vector<std::array<int,2>>ch;std::vector<Info>val;std::vector<Transform>lazy;Infoblank(intll,intrr){returnInfo(rr-ll+1,rr*(rr+1ULL)/2-ll*(ll-1ULL)/2);}Infoinfo_of(intcr,intll,intrr){returncr?val[cr]:blank(ll,rr);}voidpush_up(intcr,intll,intrr){intmm=ll+((rr-ll)>>1);val[cr]=info_of(lc(cr),ll,mm)+info_of(rc(cr),mm+1,rr);}// Build an empty tree.voidbuild(intl,intr,intn){rt=0,id=0,L=l,R=r;ch.resize(n),val.resize(n),lazy.resize(n);}// Lazy update.voidlazy_update(int&cr,intll,intrr,constTransform&f){if(!cr)val[cr=++id]=blank(ll,rr);val[cr]=f(val[cr]);lazy[cr]+=f;}// Push down lazy tag.voidpush_down(intcr,intll,intrr){if(!lazy[cr])return;intmm=ll+((rr-ll)>>1);lazy_update(lc(cr),ll,mm,lazy[cr]);lazy_update(rc(cr),mm+1,rr,lazy[cr]);lazy[cr]=Transform();}// Query info in [l, r].Infoquery(intcr,intll,intrr,inttl,inttr){if(!cr)returnblank(std::max(ll,tl),std::min(rr,tr));if(tl<=ll&&rr<=tr)returnval[cr];push_down(cr,ll,rr);intmm=ll+((rr-ll)>>1);Infores;if(tl<=mm)res=query(lc(cr),ll,mm,tl,tr);if(mm<tr)res+=query(rc(cr),mm+1,rr,tl,tr);returnres;}Infoquery(intl,intr){returnquery(rt,L,R,l,r);}// Apply transformation f to the range [l, r].voidmodify(int&cr,intll,intrr,inttl,inttr,constTransform&f){if(!cr)val[cr=++id]=blank(ll,rr);if(tl<=ll&&rr<=tr)returnlazy_update(cr,ll,rr,f);push_down(cr,ll,rr);intmm=ll+((rr-ll)>>1);if(tl<=mm)modify(lc(cr),ll,mm,tl,tr,f);if(mm<tr)modify(rc(cr),mm+1,rr,tl,tr,f);push_up(cr,ll,rr);}voidmodify(intl,intr,constTransform&f){modify(rt,L,R,l,r,f);}intmain(){std::ios::sync_with_stdio(false),std::cin.tie(nullptr);intn,m;std::cin>>n>>m;build(1,n,1.5e7);for(;m;--m){intop;std::cin>>op;if(op==1){intl,r,k;std::cin>>l>>r>>k;modify(l,r,Transform(k));}elseif(op==2){intl,r;std::cin>>l>>r;std::cout<<query(l,r).sum<<'\n';}}return0;}
#include<algorithm>#include<array>#include<iostream>#include<unordered_map>#include<vector>usingu64=unsignedlonglong;// Interval length and sum of elements.structInfo{u64len,sum;Info(u64_len=0,u64_sum=0):len(_len),sum(_sum){}Infooperator+(constInfo&o)const{returnInfo(len+o.len,sum+o.sum);}Info&operator+=(constInfo&o){return*this=*this+o;}};// Range add.structTransform{u64a;Transform(u64_a=0):a(_a){}explicitoperatorbool()const{returna!=0;}Transformoperator+(constTransform&o)const{returnTransform(a+o.a);}Transform&operator+=(constTransform&o){return*this=*this+o;}Infooperator()(constInfo&v)const{returnInfo(v.len,v.sum+a*v.len);}};// Segment Tree.// Recursive structure, stored in a full binary tree.#define lc(x) ch[(x)][0]#define rc(x) ch[(x)][1]intrt,id,L,R;std::vector<std::array<int,2>>ch;std::vector<Info>val;std::vector<Transform>lazy;voidpush_up(intcr){val[cr]=val[lc(cr)]+val[rc(cr)];}// Build the tree based on info stored in vec (0-indexed).voidbuild(intcr,intll,intrr,conststd::vector<Info>&vec){if(ll==rr)return(void)(val[cr]=vec[ll-L]);intmm=ll+((rr-ll)>>1);build(lc(cr)=++id,ll,mm,vec);build(rc(cr)=++id,mm+1,rr,vec);push_up(cr);}voidbuild(intl,intr,conststd::vector<Info>&vec){rt=1,id=0,L=l,R=r;intn=R-L+1;ch.resize(n<<1),val.resize(n<<1),lazy.resize(n<<1);build(rt=++id,L,R,vec);}// Lazy update.voidlazy_update(intcr,constTransform&f){val[cr]=f(val[cr]);lazy[cr]+=f;}// Push down lazy tag.voidpush_down(intcr){if(!lazy[cr])return;lazy_update(lc(cr),lazy[cr]);lazy_update(rc(cr),lazy[cr]);lazy[cr]=Transform();}// Query info in [l, r].Infoquery(intcr,intll,intrr,inttl,inttr){if(tl<=ll&&rr<=tr)returnval[cr];push_down(cr);intmm=ll+((rr-ll)>>1);Infores;if(tl<=mm)res=query(lc(cr),ll,mm,tl,tr);if(mm<tr)res+=query(rc(cr),mm+1,rr,tl,tr);returnres;}Infoquery(intl,intr){returnquery(rt,L,R,l,r);}// Apply transformation f to the range [l, r].voidmodify(intcr,intll,intrr,inttl,inttr,constTransform&f){if(tl<=ll&&rr<=tr)returnlazy_update(cr,f);push_down(cr);intmm=ll+((rr-ll)>>1);if(tl<=mm)modify(lc(cr),ll,mm,tl,tr,f);if(mm<tr)modify(rc(cr),mm+1,rr,tl,tr,f);push_up(cr);}voidmodify(intl,intr,constTransform&f){modify(rt,L,R,l,r,f);}intmain(){std::ios::sync_with_stdio(false),std::cin.tie(nullptr);intn,m;std::cin>>n>>m;// Offline queries and discretization.std::vector<std::array<int,4>>queries(m);std::vector<int>loc;loc.reserve((m<<1)|1);loc.push_back(0);for(auto&q:queries){std::cin>>q[0]>>q[1]>>q[2];if(q[0]==1)std::cin>>q[3];loc.push_back(q[1]-1);loc.push_back(q[2]);}std::sort(loc.begin(),loc.end());loc.erase(std::unique(loc.begin(),loc.end()),loc.end());intsz=loc.size();std::unordered_map<int,int>ids;for(inti=0;i<sz;++i)ids[loc[i]]=i;std::vector<Info>vec(sz);for(inti=1;i<sz;++i){vec[i].len=loc[i]-loc[i-1];vec[i].sum=vec[i].len*(loc[i]+loc[i-1]+1ULL)/2;}// Ordinary seg tree operations.build(0,sz-1,vec);for(autoq:queries){if(q[0]==1){modify(ids[q[1]-1]+1,ids[q[2]],Transform(q[3]));}elseif(q[0]==2){std::cout<<query(ids[q[1]-1]+1,ids[q[2]]).sum<<'\n';}}return0;}
#include<algorithm>#include<array>#include<iostream>#include<unordered_map>#include<vector>structInfo{intlen;// Length of this interval.intcnt;// Number of operations that cover this interval exactly.inttot;// Length covered by operations recorded in the descendants.};// Segment tree.intrt,id,L,R;std::vector<int>lc,rc;std::vector<Info>val;// Build the tree.voidbuild(intcr,intll,intrr,conststd::vector<int>&vec){if(ll==rr)return(void)(val[cr].len=(ll?vec[ll]-vec[ll-1]:0));intmm=ll+((rr-ll)>>1);build(lc[cr]=++id,ll,mm,vec);build(rc[cr]=++id,mm+1,rr,vec);val[cr].len=val[lc[cr]].len+val[rc[cr]].len;}voidbuild(intn,conststd::vector<int>&vec){rt=0,id=0,L=0,R=n-1;lc.resize(n<<1),rc.resize(n<<1),val.resize(n<<1);build(rt=++id,0,n-1,vec);}// Query.intquery(intcr){returnval[cr].cnt?val[cr].len:val[cr].tot;}intquery(){returnquery(rt);}// Cover.voidcover(intcr,intll,intrr,inttl,inttr,intv){if(tl<=ll&&rr<=tr)return(void)(val[cr].cnt+=v);intmm=ll+((rr-ll)>>1);if(tl<=mm)cover(lc[cr],ll,mm,tl,tr,v);if(mm<tr)cover(rc[cr],mm+1,rr,tl,tr,v);val[cr].tot=query(lc[cr])+query(rc[cr]);}voidcover(intl,intr,intv){cover(rt,L,R,l,r,v);}intmain(){std::ios::sync_with_stdio(false),std::cin.tie(nullptr);intn;std::cin>>n;// Scanning and discretizing.std::vector<std::array<int,4>>ops;ops.reserve(n<<1);std::vector<int>locs;locs.reserve(n<<1);for(inti=0;i<n;++i){intx1,y1,x2,y2;std::cin>>x1>>y1>>x2>>y2;ops.push_back({x1,y1,y2,1});ops.push_back({x2,y1,y2,-1});locs.push_back(y1);locs.push_back(y2);}std::sort(ops.begin(),ops.end());std::sort(locs.begin(),locs.end());locs.erase(std::unique(locs.begin(),locs.end()),locs.end());intm=locs.size();std::unordered_map<int,int>ids;for(inti=0;i<m;++i)ids[locs[i]]=i;// Segment tree operations.build(m,locs);longlongres=0;for(intl=0,r;l<(n<<1);l=r){for(r=l;r<(n<<1)&&ops[r][0]==ops[l][0];++r){cover(ids[ops[r][1]]+1,ids[ops[r][2]],ops[r][3]);}if(r<(n<<1))res+=(longlong)(ops[r][0]-ops[l][0])*query();}std::cout<<res<<std::endl;return0;}
#include<algorithm>#include<array>#include<climits>#include<iostream>#include<unordered_map>#include<vector>structInfo{intcnt;// Minimum cover count over this interval.intlen;// Total length of the parts attaining that minimum.Info(int_cnt=INT_MAX,int_len=0):cnt(_cnt),len(_len){}Infooperator+(constInfo&o)const{returncnt<o.cnt?*this:(cnt>o.cnt?o:Info(cnt,len+o.len));}Info&operator+=(constInfo&o){return*this=*this+o;}};structTransform{intv;Transform(int_v=0):v(_v){}explicitoperatorbool()const{returnv!=0;}Transformoperator+(constTransform&o)const{returnTransform(v+o.v);}Transform&operator+=(constTransform&o){return*this=*this+o;}Infooperator()(constInfo&x)const{returnInfo(x.cnt==INT_MAX?INT_MAX:x.cnt+v,x.len);}};classSegmentTree{intrt,id,L,R;std::vector<int>lc,rc;std::vector<Info>val;std::vector<Transform>lz;voidpush_up(intcr){val[cr]=val[lc[cr]]+val[rc[cr]];}voidlazy_update(intcr,constTransform&f){val[cr]=f(val[cr]);lz[cr]+=f;}voidpush_down(intcr){if(!lz[cr])return;lazy_update(lc[cr],lz[cr]);lazy_update(rc[cr],lz[cr]);lz[cr]=Transform();}voidbuild(intcr,intll,intrr,conststd::vector<int>&locs){if(ll==rr)return(void)(val[cr]=Info(0,ll?locs[ll]-locs[ll-1]:0));intmm=ll+((rr-ll)>>1);build(lc[cr]=++id,ll,mm,locs);build(rc[cr]=++id,mm+1,rr,locs);push_up(cr);}voidmodify(intcr,intll,intrr,inttl,inttr,constTransform&f){if(tl<=ll&&rr<=tr)returnlazy_update(cr,f);push_down(cr);intmm=ll+((rr-ll)>>1);if(tl<=mm)modify(lc[cr],ll,mm,tl,tr,f);if(mm<tr)modify(rc[cr],mm+1,rr,tl,tr,f);push_up(cr);}public:SegmentTree(intn,conststd::vector<int>&locs){rt=0,id=0,L=0,R=n-1;lc.resize(n<<1),rc.resize(n<<1),val.resize(n<<1),lz.resize(n<<1);build(rt=++id,L,R,locs);}voidmodify(intl,intr,constTransform&f){modify(rt,L,R,l,r,f);}Infoquery()const{returnval[rt];}};intmain(){std::ios::sync_with_stdio(false),std::cin.tie(nullptr);intn;std::cin>>n;// Scanning and discretizing.std::vector<std::array<int,4>>ops;ops.reserve(n<<1);std::vector<int>locs;locs.reserve(n<<1);for(inti=0;i<n;++i){intx1,y1,x2,y2;std::cin>>x1>>y1>>x2>>y2;ops.push_back({x1,y1,y2,1});ops.push_back({x2,y1,y2,-1});locs.push_back(y1);locs.push_back(y2);}std::sort(ops.begin(),ops.end());std::sort(locs.begin(),locs.end());locs.erase(std::unique(locs.begin(),locs.end()),locs.end());intm=locs.size();std::unordered_map<int,int>ids;for(inti=0;i<m;++i)ids[locs[i]]=i;// Segment tree operations.longlongall=locs.back()-locs[0];SegmentTreeseg(m,locs);longlongres=0;for(intl=0,r;l<(n<<1);l=r){for(r=l;r<(n<<1)&&ops[r][0]==ops[l][0];++r){seg.modify(ids[ops[r][1]]+1,ids[ops[r][2]],Transform(ops[r][3]));}if(r<(n<<1))res+=(ops[r][0]-ops[l][0])*(all-seg.query().len);}std::cout<<res<<std::endl;return0;}
#include<algorithm>#include<iostream>#include<vector>// Interval info.// lt - longest prefix run.// rt - longest suffix run.// ma - longest run.// len - interval length.structInfo{intlt,rt,ma,len;Info(int_lt=0,int_rt=0,int_ma=0,int_len=0):lt(_lt),rt(_rt),ma(_ma),len(_len){}Infooperator+(constInfo&o)const{auto_lt=lt==len?len+o.lt:lt;auto_rt=o.rt==o.len?rt+o.len:o.rt;returnInfo(_lt,_rt,std::max({_lt,_rt,rt+o.lt,ma,o.ma}),len+o.len);}Info&operator+=(constInfo&o){return*this=*this+o;}};// Assignment.structTransform{intv;Transform(int_v=-1):v(_v){}explicitoperatorbool()const{returnv!=-1;}Transformoperator+(constTransform&o)const{returno?o:*this;}Transform&operator+=(constTransform&o){return*this=*this+o;}Infooperator()(constInfo&x)const{returnv==1?Info(0,0,0,x.len):(v==0?Info(x.len,x.len,x.len,x.len):x);}};// Segment tree.classSegmentTree{intrt,id,L,R;std::vector<int>lc,rc;std::vector<Info>val;std::vector<Transform>lz;voidpush_up(intcr){val[cr]=val[lc[cr]]+val[rc[cr]];}voidlazy_update(intcr,constTransform&f){val[cr]=f(val[cr]);lz[cr]+=f;}voidpush_down(intcr){if(!lz[cr])return;lazy_update(lc[cr],lz[cr]);lazy_update(rc[cr],lz[cr]);lz[cr]=Transform();}voidbuild(intcr,intll,intrr){if(ll==rr)return(void)(val[cr]=Info(1,1,1,1));intmm=ll+((rr-ll)>>1);build(lc[cr]=++id,ll,mm);build(rc[cr]=++id,mm+1,rr);push_up(cr);}voidmodify(intcr,intll,intrr,inttl,inttr,constTransform&f){if(tl<=ll&&rr<=tr)returnlazy_update(cr,f);push_down(cr);intmm=ll+((rr-ll)>>1);if(tl<=mm)modify(lc[cr],ll,mm,tl,tr,f);if(mm<tr)modify(rc[cr],mm+1,rr,tl,tr,f);push_up(cr);}template<typenameG>intlower_bound(intcr,intll,intrr,constG&g,constInfo&acc){if(ll==rr)returnll;push_down(cr);intmm=ll+((rr-ll)>>1);returng(acc+val[lc[cr]])?lower_bound(lc[cr],ll,mm,g,acc):lower_bound(rc[cr],mm+1,rr,g,acc+val[lc[cr]]);}public:SegmentTree(intn):rt(0),id(0),L(1),R(n){lc.resize(n<<1),rc.resize(n<<1),val.resize(n<<1),lz.resize(n<<1);build(rt=++id,L,R);}// Apply f to [l,r].voidmodify(intl,intr,constTransform&f){modify(rt,L,R,l,r,f);}// Find the lowest r such that g(info([1,r])) is true.template<typenameG>intlower_bound(constG&g){returng(val[rt])?lower_bound(rt,L,R,g,Info()):R+1;}};intmain(){intn,m;std::cin>>n>>m;SegmentTreeseg(n);for(;m;--m){intop;std::cin>>op;if(op==1){intx;std::cin>>x;autoy=seg.lower_bound([&](constInfo&v)->bool{returnv.ma>=x;});if(y<=n){std::cout<<(y-x+1)<<'\n';seg.modify(y-x+1,y,Transform(1));}else{std::cout<<0<<'\n';}}elseif(op==2){intx,y;std::cin>>x>>y;seg.modify(x,x+y-1,Transform(0));}}return0;}