2#include"../../kyopro_library/template.hpp"
8template<
typename Monoid,
typename Operator,
auto mapping>
10 using MonoidType=
typename Monoid::Type;
11 using OperatorType=
typename Operator::Type;
17 dat.assign(n<<1,Monoid::id());
18 lazy.assign(n<<1,Operator::id());
24 dat.assign(n<<1,Monoid::id());
25 lazy.assign(n<<1,Operator::id());
26 for(
int i=0; i<n; i++) dat[i+n]=v[i];
27 for(
int i=n-1; i>0; i--) dat[i]=Monoid::op(dat[i<<1],dat[i<<1|1]);
31 void set(
int i, MonoidType x) {
32 generate_indices(i,i+1);
36 while(i>>=1) dat[i]=Monoid::op(dat[i<<1],dat[i<<1|1]);
40 void apply(
int l,
int r, OperatorType x) {
42 generate_indices(l,r);
47 lazy[l]=Operator::op(lazy[l],x);
48 dat[l]=mapping(dat[l],x);
53 lazy[r]=Operator::op(lazy[r],x);
54 dat[r]=mapping(dat[r],x);
62 MonoidType
fold(
int l,
int r) {
63 if(l==r)
return Monoid::id();
64 generate_indices(l,r);
66 MonoidType retl=Monoid::id(),retr=Monoid::id();
69 if(l&1) retl=Monoid::op(retl,dat[l++]);
70 if(r&1) retr=Monoid::op(dat[--r],retr);
73 return Monoid::op(retl,retr);
81 assert(f(Monoid::id()));
83 generate_indices(l,n);
87 vector<
int> cand_l,cand_r;
89 if(l&1) cand_l.push_back(l++);
90 if(r&1) cand_r.push_back(--r);
93 vector<
int> cand=cand_l;
94 reverse(cand_r.begin(),cand_r.end());
95 cand.insert(cand.end(),cand_r.begin(),cand_r.end());
96 MonoidType val=Monoid::id();
98 if(f(Monoid::op(val,dat[i]))) {
99 val=Monoid::op(val,dat[i]);
104 if(f(Monoid::op(val,dat[i]))) {
105 val=Monoid::op(val,dat[i]);
120 assert(f(Monoid::id()));
122 generate_indices(0,r);
126 vector<
int> cand_l,cand_r;
128 if(l&1) cand_l.push_back(l++);
129 if(r&1) cand_r.push_back(--r);
132 vector<
int> cand=cand_r;
133 reverse(cand_l.begin(),cand_l.end());
134 cand.insert(cand.end(),cand_l.begin(),cand_l.end());
135 MonoidType val=Monoid::id();
137 if(f(Monoid::op(dat[i],val))) {
138 val=Monoid::op(dat[i],val);
143 if(f(Monoid::op(dat[i],val))) {
144 val=Monoid::op(dat[i],val);
159 vector<MonoidType> dat;
160 vector<OperatorType> lazy;
162 void generate_indices(
int l,
int r) {
165 int lm=(l/(l&-l))>>1,rm=(r/(r&-r))>>1;
167 if(l<=lm) indices.push_back(l);
168 if(r<=rm) indices.push_back(r);
172 indices.push_back(l);
176 void propagate(
int i) {
178 lazy[i<<1]=Operator::op(lazy[i<<1],lazy[i]);
179 lazy[i<<1|1]=Operator::op(lazy[i<<1|1],lazy[i]);
180 dat[i<<1]=mapping(dat[i<<1],lazy[i]);
181 dat[i<<1|1]=mapping(dat[i<<1|1],lazy[i]);
183 lazy[i]=Operator::id();
186 for(
int j=(
int)indices.size()-1; j>=0; j--) {
192 for(
int j=0; j<(
int)indices.size(); j++) {
194 dat[i]=Monoid::op(dat[i<<1],dat[i<<1|1]);
199#include"../../kyopro_library/others/monoid.hpp"
200#include"../../kyopro_library/others/operator.hpp"
206 template<
typename T, T max_value, T not_exist>
208 static T
mapping(
const T& a,
const T& b) {
return b==not_exist?a:b; }
215 template<
typename T, T min_value, T not_exist>
217 static T
mapping(
const T& a,
const T& b) {
return b==not_exist?a:b; }
223 template<
typename T, T not_exist>
226 static S
mapping(
const S& a,
const T& b) {
return b==not_exist?a:S{b*a.second,a.second}; }
231 template<
typename T, T max_value>
233 static T
mapping(
const T& a,
const T& b) {
return a+b; }
238 template<
typename T, T min_value>
240 static T
mapping(
const T& a,
const T& b) {
return a+b; }
248 static S
mapping(
const S& a,
const T& b) {
return {a.first+b*a.second,a.second}; }
static T mapping(const T &a, const T &b)
static T mapping(const T &a, const T &b)
static S mapping(const S &a, const T &b)
static T mapping(const T &a, const T &b)
static T mapping(const T &a, const T &b)
static S mapping(const S &a, const T &b)
SegTreeLazy(const vector< MonoidType > &v)
配列 v から遅延セグ木を構築する
void apply(int l, int r, OperatorType x)
区間 [l, r) に x を作用させる
MonoidType fold(int l, int r)
区間 [l, r) のモノイド積を返す
int find_left(int r, F f)
区間 [x, r) のモノイド積が f を満たすような最小の x<=r を返す
MonoidType operator[](int i)
int find_right(int l, F f)
区間 [l, x) のモノイド積が f を満たすような最大の x >= l を返す
void set(int i, MonoidType x)
i 番目の要素を x に更新する
SegTreeLazy(int n)
要素数 n の遅延セグ木を構築する