#include "segment_tree/segment_tree.hpp"
#pragma once #include<vector> #include"../alga/maybe.hpp" /** * @brief セグメント木 * @see https://en.wikipedia.org/wiki/Segment_tree */ template<typename T,typename F> class segment_tree{ maybe<T>* node; F op; int n=1; public: segment_tree(){} segment_tree(int sz,F op=F()):op(op){ while(n<=sz)n<<=1; node=new maybe<T>[n*2]; for(int i=0;i<n*2;i++)node[i]=maybe<T>(); } segment_tree(const std::vector<T>&v,F op=F()):op(op){ auto f=expand<T,F>(op); const int sz=v.size(); while(n<=sz)n<<=1; node=new maybe<T>[n*2](); for(int i=0;i<sz;i++)node[i+n]=maybe<T>(v[i]); for(int i=n-1;i>=1;i--)node[i]=f(node[i*2],node[i*2+1]); } maybe<T> get(int l,int r){ auto f=expand<T,F>(op); l+=n;r+=n; maybe<T> s,t; while(l<r){ if(l&1)s=f(s,node[l++]); if(r&1)t=f(node[--r],t); l>>=1;r>>=1; } return f(s,t); } void apply(int t,T _val){ auto f=expand<T,F>(op); t+=n; maybe<T> val=maybe<T>(_val); while(t){ node[t]=f(node[t],val); t=t>>1; } } void apply_left(int t,T _val){ auto f=expand<T,F>(op); t+=n; maybe<T> val=maybe<T>(_val); while(t){ node[t]=f(val,node[t]); t=t>>1; } } void change(int t,T val){ auto f=expand<T,F>(op); t+=n; node[t]=maybe<T>(val); while(t>1){ t=t>>1; node[t]=f(node[t*2],node[t*2+1]); } } };
#line 2 "segment_tree/segment_tree.hpp" #include<vector> #line 2 "alga/maybe.hpp" #include<cassert> /** * @brief Maybe * @see https://ja.wikipedia.org/wiki/%E3%83%A2%E3%83%8A%E3%83%89_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)#Maybe%E3%83%A2%E3%83%8A%E3%83%89 */ template<typename T> struct maybe{ bool _is_none; T val; maybe():_is_none(true){} maybe(T val):_is_none(false),val(val){} T unwrap()const{ assert(!_is_none); return val; } T unwrap_or(T e)const{ return _is_none?e:val; } bool is_none()const{return _is_none;} bool is_some()const{return !_is_none;} }; template<typename T,typename F> auto expand(F op){ return [&op](const maybe<T>& s,const maybe<T>& t){ if(s.is_none())return t; if(t.is_none())return s; return maybe<T>(op(s.unwrap(),t.unwrap())); }; } #line 4 "segment_tree/segment_tree.hpp" /** * @brief セグメント木 * @see https://en.wikipedia.org/wiki/Segment_tree */ template<typename T,typename F> class segment_tree{ maybe<T>* node; F op; int n=1; public: segment_tree(){} segment_tree(int sz,F op=F()):op(op){ while(n<=sz)n<<=1; node=new maybe<T>[n*2]; for(int i=0;i<n*2;i++)node[i]=maybe<T>(); } segment_tree(const std::vector<T>&v,F op=F()):op(op){ auto f=expand<T,F>(op); const int sz=v.size(); while(n<=sz)n<<=1; node=new maybe<T>[n*2](); for(int i=0;i<sz;i++)node[i+n]=maybe<T>(v[i]); for(int i=n-1;i>=1;i--)node[i]=f(node[i*2],node[i*2+1]); } maybe<T> get(int l,int r){ auto f=expand<T,F>(op); l+=n;r+=n; maybe<T> s,t; while(l<r){ if(l&1)s=f(s,node[l++]); if(r&1)t=f(node[--r],t); l>>=1;r>>=1; } return f(s,t); } void apply(int t,T _val){ auto f=expand<T,F>(op); t+=n; maybe<T> val=maybe<T>(_val); while(t){ node[t]=f(node[t],val); t=t>>1; } } void apply_left(int t,T _val){ auto f=expand<T,F>(op); t+=n; maybe<T> val=maybe<T>(_val); while(t){ node[t]=f(val,node[t]); t=t>>1; } } void change(int t,T val){ auto f=expand<T,F>(op); t+=n; node[t]=maybe<T>(val); while(t>1){ t=t>>1; node[t]=f(node[t*2],node[t*2+1]); } } };