This documentation is automatically generated by online-judge-tools/verification-helper
#include "data-structure/segment-tree/lazy-segment-tree.hpp"
#pragma once
/**
* Author: Teetat T.
* Date: 2024-01-15
* Description: Segment Tree with Lazy Propagation
*/
template<class MonoidAction>
struct LazySegmentTree{
using InfoMonoid = typename MonoidAction::InfoMonoid;
using TagMonoid = typename MonoidAction::TagMonoid;
using Info = typename MonoidAction::Info;
using Tag = typename MonoidAction::Tag;
int n;
vector<Info> t;
vector<Tag> lz;
LazySegmentTree(){}
LazySegmentTree(int n,function<Info(int)> create){init(n,create);}
LazySegmentTree(int n,Info v=InfoMonoid::unit()){init(n,[&](int){return v;});}
template<class T>
LazySegmentTree(const vector<T> &a){init((int)a.size(),[&](int i){return Info(a[i]);});}
void init(int _n,function<Info(int)> create){
n=_n;
int m=4<<(31-__builtin_clz(n));
t.assign(m,InfoMonoid::unit());
lz.assign(m,TagMonoid::unit());
function<void(int,int,int)> build=[&](int l,int r,int i){
if(l==r)return void(t[i]=create(l));
int m=(l+r)/2;
build(l,m,i*2);
build(m+1,r,i*2+1);
pull(i);
};
build(0,n-1,1);
}
void pull(int i){
t[i]=InfoMonoid::op(t[i*2],t[i*2+1]);
}
void apply(int i,const Tag &v){
t[i]=MonoidAction::op(t[i],v);
lz[i]=TagMonoid::op(lz[i],v);
}
void push(int i){
apply(i*2,lz[i]);
apply(i*2+1,lz[i]);
lz[i]=TagMonoid::unit();
}
void modify(int l,int r,int i,int x,const Info &v){
if(x<l||r<x)return;
if(l==r)return void(t[i]=v);
int m=(l+r)/2;
push(i);
modify(l,m,i*2,x,v);
modify(m+1,r,i*2+1,x,v);
pull(i);
}
void modify(int x,const Info &v){
modify(0,n-1,1,x,v);
}
void update(int l,int r,int i,int x,int y,const Tag &v){
if(y<l||r<x)return;
if(x<=l&&r<=y)return apply(i,v);
int m=(l+r)/2;
push(i);
update(l,m,i*2,x,y,v);
update(m+1,r,i*2+1,x,y,v);
pull(i);
}
void update(int x,int y,const Tag &v){
update(0,n-1,1,x,y,v);
}
Info query(int l,int r,int i,int x,int y){
if(y<l||r<x)return InfoMonoid::unit();
if(x<=l&&r<=y)return t[i];
int m=(l+r)/2;
push(i);
return InfoMonoid::op(query(l,m,i*2,x,y),query(m+1,r,i*2+1,x,y));
}
Info query(int x,int y){
return query(0,n-1,1,x,y);
}
template<class F>
int findfirst(int l,int r,int i,int x,int y,const F &f){
if(y<l||r<x||!f(t[i]))return n;
if(l==r)return l;
int m=(l+r)/2;
push(i);
int res=findfirst(l,m,i*2,x,y,f);
if(res==n)res=findfirst(m+1,r,i*2+1,x,y,f);
return res;
}
template<class F>
int findfirst(int x,int y,const F &f){
return findfirst(0,n-1,1,x,y,f);
}
template<class F>
int findlast(int l,int r,int i,int x,int y,const F &f){
if(y<l||r<x||!f(t[i]))return -1;
if(l==r)return l;
int m=(l+r)/2;
push(i);
int res=findlast(m+1,r,i*2+1,x,y,f);
if(res==-1)res=findlast(l,m,i*2,x,y,f);
return res;
}
template<class F>
int findlast(int x,int y,const F &f){
return findlast(0,n-1,1,x,y,f);
}
};
#line 2 "data-structure/segment-tree/lazy-segment-tree.hpp"
/**
* Author: Teetat T.
* Date: 2024-01-15
* Description: Segment Tree with Lazy Propagation
*/
template<class MonoidAction>
struct LazySegmentTree{
using InfoMonoid = typename MonoidAction::InfoMonoid;
using TagMonoid = typename MonoidAction::TagMonoid;
using Info = typename MonoidAction::Info;
using Tag = typename MonoidAction::Tag;
int n;
vector<Info> t;
vector<Tag> lz;
LazySegmentTree(){}
LazySegmentTree(int n,function<Info(int)> create){init(n,create);}
LazySegmentTree(int n,Info v=InfoMonoid::unit()){init(n,[&](int){return v;});}
template<class T>
LazySegmentTree(const vector<T> &a){init((int)a.size(),[&](int i){return Info(a[i]);});}
void init(int _n,function<Info(int)> create){
n=_n;
int m=4<<(31-__builtin_clz(n));
t.assign(m,InfoMonoid::unit());
lz.assign(m,TagMonoid::unit());
function<void(int,int,int)> build=[&](int l,int r,int i){
if(l==r)return void(t[i]=create(l));
int m=(l+r)/2;
build(l,m,i*2);
build(m+1,r,i*2+1);
pull(i);
};
build(0,n-1,1);
}
void pull(int i){
t[i]=InfoMonoid::op(t[i*2],t[i*2+1]);
}
void apply(int i,const Tag &v){
t[i]=MonoidAction::op(t[i],v);
lz[i]=TagMonoid::op(lz[i],v);
}
void push(int i){
apply(i*2,lz[i]);
apply(i*2+1,lz[i]);
lz[i]=TagMonoid::unit();
}
void modify(int l,int r,int i,int x,const Info &v){
if(x<l||r<x)return;
if(l==r)return void(t[i]=v);
int m=(l+r)/2;
push(i);
modify(l,m,i*2,x,v);
modify(m+1,r,i*2+1,x,v);
pull(i);
}
void modify(int x,const Info &v){
modify(0,n-1,1,x,v);
}
void update(int l,int r,int i,int x,int y,const Tag &v){
if(y<l||r<x)return;
if(x<=l&&r<=y)return apply(i,v);
int m=(l+r)/2;
push(i);
update(l,m,i*2,x,y,v);
update(m+1,r,i*2+1,x,y,v);
pull(i);
}
void update(int x,int y,const Tag &v){
update(0,n-1,1,x,y,v);
}
Info query(int l,int r,int i,int x,int y){
if(y<l||r<x)return InfoMonoid::unit();
if(x<=l&&r<=y)return t[i];
int m=(l+r)/2;
push(i);
return InfoMonoid::op(query(l,m,i*2,x,y),query(m+1,r,i*2+1,x,y));
}
Info query(int x,int y){
return query(0,n-1,1,x,y);
}
template<class F>
int findfirst(int l,int r,int i,int x,int y,const F &f){
if(y<l||r<x||!f(t[i]))return n;
if(l==r)return l;
int m=(l+r)/2;
push(i);
int res=findfirst(l,m,i*2,x,y,f);
if(res==n)res=findfirst(m+1,r,i*2+1,x,y,f);
return res;
}
template<class F>
int findfirst(int x,int y,const F &f){
return findfirst(0,n-1,1,x,y,f);
}
template<class F>
int findlast(int l,int r,int i,int x,int y,const F &f){
if(y<l||r<x||!f(t[i]))return -1;
if(l==r)return l;
int m=(l+r)/2;
push(i);
int res=findlast(m+1,r,i*2+1,x,y,f);
if(res==-1)res=findlast(l,m,i*2,x,y,f);
return res;
}
template<class F>
int findlast(int x,int y,const F &f){
return findlast(0,n-1,1,x,y,f);
}
};