#ifndef AFDS_APPEAR_STATISTICS
#define AFDS_APPEAR_STATISTICS
#include"discretization.hpp"
#include<vector>template<classT>classAppearStats{// Appear Statistics.private:Mess<T>M;size_tn;std::vector<std::vector<int>>pos;public:AppearStats(void):n(0){}AppearStats(std::vector<T>&init):n(init.size()){_init(init);}inlinevoid_init(std::vector<T>&init){for(autoitem:init)M.insert(item);n=init.size(),M.init(),pos.resize(M.v.size());for(size_ti=0;i<n;i++){pos[M.query(init[i])-1].push_back(i);}}// Use「base」as the beginning of index, return -1 if x doesn't exist.inlineintfirst(intl,intr,Tx,intbase=0){l-=base,r-=base;if(!M.exist(x))return-1;std::vector<int>&P=pos[M.query(x)-1];autoit=std::lower_bound(P.begin(),P.end(),l);returnit==P.end()||*it>r?-1:*it+base;}// Use「base」as the beginning of index, return -1 if x doesn't exist.inlineintlast(intl,intr,Tx,intbase=0){l-=base,r-=base;if(!M.exist(x))return-1;std::vector<int>&P=pos[M.query(x)-1];autoit=std::upper_bound(P.begin(),P.end(),r);returnit==P.begin()||*std::prev(it)<l?-1:*std::prev(it)+base;}inlineintcount(intl,intr,Tx,intbase=0){l-=base,r-=base;if(l>r||!M.exist(x))return0;std::vector<int>&P=pos[M.query(x)-1];autoL=std::lower_bound(P.begin(),P.end(),l);autoR=std::upper_bound(P.begin(),P.end(),r);if(L==P.end()||R==P.begin())return0;if(*L>r||*std::prev(R)<l)return0;returnR-L;}};#endif // AFDS_APPEAR_STATISTICS
#line 1 "src/alfred/data_structure/appear-statistics.hpp"
#line 1 "src/alfred/data_structure/discretization.hpp"
#include<algorithm>
#include<vector>template<class_Tp>structMess{std::vector<_Tp>v;boolinitialized=false;inline_Tporigin(intidx){returnv[idx-1];}inlinevoidinsert(_Tpx){v.push_back(x);}template<typenameT,typename...V>inlinevoidinsert(Tx,V...v){insert(x),insert(v...);}inlinevoidinit(void){std::sort(v.begin(),v.end()),initialized=true;v.erase(unique(v.begin(),v.end()),v.end());}inlinevoidclear(void){v.clear(),initialized=false;}inlineintquery(_Tpx){if(!initialized)init();returnstd::lower_bound(v.begin(),v.end(),x)-v.begin()+1;}inlineboolexist(_Tpx){returnorigin(query(x))==x;}};#line 6 "src/alfred/data_structure/appear-statistics.hpp"
template<classT>classAppearStats{// Appear Statistics.private:Mess<T>M;size_tn;std::vector<std::vector<int>>pos;public:AppearStats(void):n(0){}AppearStats(std::vector<T>&init):n(init.size()){_init(init);}inlinevoid_init(std::vector<T>&init){for(autoitem:init)M.insert(item);n=init.size(),M.init(),pos.resize(M.v.size());for(size_ti=0;i<n;i++){pos[M.query(init[i])-1].push_back(i);}}// Use「base」as the beginning of index, return -1 if x doesn't exist.inlineintfirst(intl,intr,Tx,intbase=0){l-=base,r-=base;if(!M.exist(x))return-1;std::vector<int>&P=pos[M.query(x)-1];autoit=std::lower_bound(P.begin(),P.end(),l);returnit==P.end()||*it>r?-1:*it+base;}// Use「base」as the beginning of index, return -1 if x doesn't exist.inlineintlast(intl,intr,Tx,intbase=0){l-=base,r-=base;if(!M.exist(x))return-1;std::vector<int>&P=pos[M.query(x)-1];autoit=std::upper_bound(P.begin(),P.end(),r);returnit==P.begin()||*std::prev(it)<l?-1:*std::prev(it)+base;}inlineintcount(intl,intr,Tx,intbase=0){l-=base,r-=base;if(l>r||!M.exist(x))return0;std::vector<int>&P=pos[M.query(x)-1];autoL=std::lower_bound(P.begin(),P.end(),l);autoR=std::upper_bound(P.begin(),P.end(),r);if(L==P.end()||R==P.begin())return0;if(*L>r||*std::prev(R)<l)return0;returnR-L;}};