This documentation is automatically generated by online-judge-tools/verification-helper
#include "data-structure/segment-tree/segment-tree.hpp"
#pragma once
/**
* Author: Teetat T.
* Date: 2024-01-15
* Description: Segment Tree
*/
template<class Monoid>
struct SegmentTree{
using T = typename Monoid::value_type;
int n;
vector<T> t;
SegmentTree(){}
SegmentTree(int n,function<T(int)> create){init(n,create);}
SegmentTree(int n,T v=Monoid::unit()){init(n,[&](int){return v;});}
template<class U>
SegmentTree(const vector<U> &a){init((int)a.size(),[&](int i){return T(a[i]);});}
void init(int _n,function<T(int)> create){
n=_n;
t.assign(4<<(31-__builtin_clz(n)),Monoid::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]=Monoid::op(t[i*2],t[i*2+1]);
}
void modify(int l,int r,int i,int x,const T &v){
if(x<l||r<x)return;
if(l==r)return void(t[i]=v);
int m=(l+r)/2;
modify(l,m,i*2,x,v);
modify(m+1,r,i*2+1,x,v);
pull(i);
}
void modify(int x,const T &v){
modify(0,n-1,1,x,v);
}
template<class U>
void update(int l,int r,int i,int x,const U &v){
if(x<l||r<x)return;
if(l==r)return void(t[i]=Monoid::op(t[i],v));
int m=(l+r)/2;
update(l,m,i*2,x,v);
update(m+1,r,i*2+1,x,v);
pull(i);
}
template<class U>
void update(int x,const U &v){
update(0,n-1,1,x,v);
}
T query(int l,int r,int i,int x,int y){
if(y<l||r<x)return Monoid::unit();
if(x<=l&&r<=y)return t[i];
int m=(l+r)/2;
return Monoid::op(query(l,m,i*2,x,y),query(m+1,r,i*2+1,x,y));
}
T 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;
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;
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/segment-tree.hpp"
/**
* Author: Teetat T.
* Date: 2024-01-15
* Description: Segment Tree
*/
template<class Monoid>
struct SegmentTree{
using T = typename Monoid::value_type;
int n;
vector<T> t;
SegmentTree(){}
SegmentTree(int n,function<T(int)> create){init(n,create);}
SegmentTree(int n,T v=Monoid::unit()){init(n,[&](int){return v;});}
template<class U>
SegmentTree(const vector<U> &a){init((int)a.size(),[&](int i){return T(a[i]);});}
void init(int _n,function<T(int)> create){
n=_n;
t.assign(4<<(31-__builtin_clz(n)),Monoid::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]=Monoid::op(t[i*2],t[i*2+1]);
}
void modify(int l,int r,int i,int x,const T &v){
if(x<l||r<x)return;
if(l==r)return void(t[i]=v);
int m=(l+r)/2;
modify(l,m,i*2,x,v);
modify(m+1,r,i*2+1,x,v);
pull(i);
}
void modify(int x,const T &v){
modify(0,n-1,1,x,v);
}
template<class U>
void update(int l,int r,int i,int x,const U &v){
if(x<l||r<x)return;
if(l==r)return void(t[i]=Monoid::op(t[i],v));
int m=(l+r)/2;
update(l,m,i*2,x,v);
update(m+1,r,i*2+1,x,v);
pull(i);
}
template<class U>
void update(int x,const U &v){
update(0,n-1,1,x,v);
}
T query(int l,int r,int i,int x,int y){
if(y<l||r<x)return Monoid::unit();
if(x<=l&&r<=y)return t[i];
int m=(l+r)/2;
return Monoid::op(query(l,m,i*2,x,y),query(m+1,r,i*2+1,x,y));
}
T 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;
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;
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);
}
};