boost
using bit=boost::dynamic_bitset<>; using mi=boost::multiprecision::cpp_int; using mf=boost::multiprecision::cpp_dec_float_100;
定数
const char en='\n'; const long long inf=2000000000000000000; const long long maxll=9223372036854775807; const long long maxabc=26; const long long mod1=1000000007; const long long mod9=998244353; const double pi=3.141592653589; const char sp=' ';
primitive
using bo=bool; using ch=char; using ll=long long; using vo=void; using uni=unsigned int; using unll=unsigned long long;
pa, tr, qu
変数取得や加減乗除の operator を追加した tuple
template<class A,class B>struct pa{ pair<A,B> raw; auto operator<=>(const pa&)const=default; pa(){} pa(A a,B b):raw(a,b){} pa(pair<A,B> p):raw(p){} auto operator()(ll i){ return(i==0)?raw.first:raw.second; } pa& operator=(const pa& r){ raw=r.raw; return *this; } pa operator+(const pa& r){ pa ret(raw); ret+=r; return ret; } pa operator-(const pa& r){ pa ret(raw); ret-=r; return ret; } pa operator*(const pa& r){ pa ret(raw); ret*=r; return ret; } pa operator/(const pa& r){ pa ret(raw); ret/=r; return ret; } pa& operator+=(const pa& r){ raw.first+=r.raw.first,raw.second+=r.raw.second; return *this; } pa& operator-=(const pa& r){ raw.first-=r.raw.first,raw.second-=r.raw.second; return *this; } pa& operator*=(const pa& r){ raw.first*=r.raw.first,raw.second*=r.raw.second; return *this; } pa& operator/=(const pa& r){ raw.first/=r.raw.first,raw.second/=r.raw.second; return *this; } }; template<class A,class B,class C>struct tr{ tuple<A,B,C> raw; auto operator<=>(const tr&)const=default; tr(){} tr(A a,B b,C c):raw(a,b,c){} tr(tuple<A,B,C> t):raw(t){} auto operator()(ll i){ return(i==0)?get<0>(raw):(i==1)?get<1>(raw):get<2>(raw); } tr operator+(const tr& r){ tr ret(raw); ret+=r; return ret; } tr operator-(const tr& r){ tr ret(raw); ret-=r; return ret; } tr operator*(const tr& r){ tr ret(raw); ret*=r; return ret; } tr operator/(const tr& r){ tr ret(raw); ret/=r; return ret; } tr& operator+=(const tr& r){ get<0>(raw)+=get<0>(r.raw),get<1>(raw)+=get<1>(r.raw),get<2>(raw)+=get<2>(r.raw); return *this; } tr& operator-=(const tr& r){ get<0>(raw)-=get<0>(r.raw),get<1>(raw)-=get<1>(r.raw),get<2>(raw)-=get<2>(r.raw); return *this; } tr& operator*=(const tr& r){ get<0>(raw)*=get<0>(r.raw),get<1>(raw)*=get<1>(r.raw),get<2>(raw)*=get<2>(r.raw); return *this; } tr& operator/=(const tr& r){ get<0>(raw)/=get<0>(r.raw),get<1>(raw)/=get<1>(r.raw),get<2>(raw)/=get<2>(r.raw); return *this; } }; template<class A,class B,class C,class D>struct qu{ tuple<A,B,C,D> raw; auto operator<=>(const qu&)const=default; qu(){} qu(A a,B b,C c,D d):raw(a,b,c,d){} qu(tuple<A,B,C,D> q):raw(q){} auto operator()(ll i){ return(i==0)?get<0>(raw):(i==1)?get<1>(raw):(i==2)?get<2>(raw):get<3>(raw); } qu operator+(const qu& r){ qu ret(raw); ret+=r; return ret; } qu operator-(const qu& r){ qu ret(raw); ret-=r; return ret; } qu operator*(const qu& r){ qu ret(raw); ret*=r; return ret; } qu operator/(const qu& r){ qu ret(raw); ret/=r; return ret; } qu& operator+=(const qu& r){ get<0>(raw)+=get<0>(r.raw),get<1>(raw)+=get<1>(r.raw),get<2>(raw)+=get<2>(r.raw),get<3>(raw)+=get<3>(r.raw); return *this; } qu& operator-=(const qu& r){ get<0>(raw)-=get<0>(r.raw),get<1>(raw)-=get<1>(r.raw),get<2>(raw)-=get<2>(r.raw),get<3>(raw)-=get<3>(r.raw); return *this; } qu& operator*=(const qu& r){ get<0>(raw)*=get<0>(r.raw),get<1>(raw)*=get<1>(r.raw),get<2>(raw)*=get<2>(r.raw),get<3>(raw)*=get<3>(r.raw); return *this; } qu& operator/=(const qu& r){ get<0>(raw)/=get<0>(r.raw),get<1>(raw)/=get<1>(r.raw),get<2>(raw)/=get<2>(r.raw),get<3>(raw)/=get<3>(r.raw); return *this; } }; using pall=pa<ll,ll>; using trlll=tr<ll,ll,ll>; using qullll=qu<ll,ll,ll,ll>;
サンプル入力
int main() { pall test1(1,10); pair<ll,ll> p=test1.raw; debug(p.first,p.second); trlll test2(2,20,200),test3(3,30,300); test2+=test3; debug(test2(0),test2(1),test2(2)); qullll test4(4,40,400,4000),test5(5,50,500,5000); qullll test6=test4+test5; debug(test6(0),test6(1),test6(2),test6(3)); return 0; }
サンプル出力
p.first,p.second=1,10 test2(0),test2(1),test2(2)=5,50,500 test6(0),test6(1),test6(2),test6(3)=9,90,900,9000
cvec
独自機能を追加した vector
sizeをll型で返す、push_backの関数名をpubに短縮、添字演算子の多次元サポート、など。
template<class X>struct cvec1{ vector<X> raw; cvec1(){} cvec1(ll xsz):raw(xsz){} cvec1(ll xsz,X init):raw(xsz,init){} auto& operator[](ll i){ return raw[i]; } auto back(){ return raw.back(); } auto begin(){ return raw.begin(); } auto end(){ return raw.end(); } auto pob(){ auto res=raw.back(); raw.pop_back(); return res; } vo pub(auto& x){ raw.push_back(x); } vo resize(ll n){ raw.resize(n); } auto size(){ return (ll)raw.size(); } }; template<class X>struct cvec2{ vector<cvec1<X>> raw; cvec2(ll ysz,ll xsz):raw(ysz,cvec1<X>(xsz)){} cvec2(ll ysz,ll xsz,X init):raw(ysz,cvec1<X>(xsz,init)){} auto& operator[](ll i){ return raw[i]; } auto& operator[](ll j,ll i){ return raw[j][i]; } auto back(){ return raw.back(); } auto begin(){ return raw.begin(); } auto end(){ return raw.end(); } auto pob(){ auto res=raw.back(); raw.pop_back(); return res; } vo pub(auto& x){ raw.push_back(x); } vo resize(ll n){ raw.resize(n); } auto size(){ return (ll)raw.size(); } }; template<class X>struct cvec3{ vector<cvec2<X>> raw; cvec3(ll zsz,ll ysz,ll xsz):raw(zsz,cvec2<X>(ysz,xsz)){} cvec3(ll zsz,ll ysz,ll xsz,X init):raw(zsz,covec2<X>(ysz,xsz,init)){} auto& operator[](ll i){ return raw[i]; } auto& operator[](ll j,ll i){ return raw[j][i]; } auto& operator[](ll k,ll j,ll i){ return raw[k][j][i]; } auto back(){ return raw.back(); } auto begin(){ return raw.begin(); } auto end(){ return raw.end(); } auto pob(){ auto res=raw.back(); raw.pop_back(); return res; } vo pub(auto& x){ raw.push_back(x); } vo resize(ll n){ raw.resize(n); } auto size(){ return (ll)raw.size(); } }; template<class X>using cv=cvec1<X>; using cvc=cv<ch>; using cvl=cv<ll>; using cvs=cv<str>; using cvpall=cv<pall>; using cvtrlll=cv<trlll>; using cvqullll=cv<qullll>;
サンプル入力
int main() { cvvl test(3,3); test[1,1]=1; debugxy(test); return 0; }
サンプル出力
test[0][]=[0]0[1]0[2]0 test[1][]=[0]0[1]1[2]0 test[2][]=[0]0[1]0[2]0
cdeq
独自機能を追加した deque
sizeをll型で返す、push_backの関数名をpubに短縮、添字演算子の多次元サポート、など。
template<class X>struct cdeq1{ deque<X> raw; cdeq1(){} cdeq1(ll sz):raw(sz){} X& operator[](ll i){ return raw[i]; } X back(){ return raw.back(); } auto begin(){ return raw.begin(); } auto end(){ return raw.end(); } X front(){ return raw.front(); } X pob(){ X ret=raw.back(); raw.pop_back(); return ret; } X pof(){ X ret=raw.front(); raw.pop_front(); return ret; } vo pub(X x){ raw.push_back(x); } vo puf(X x){ raw.push_front(x); } vo resize(ll n){ raw.resize(n); } auto size(){ return (ll)raw.size(); } }; template<class X>struct cdeq2{ deque<cdeq1<X>> raw; cdeq2(){} cdeq2(ll ysz,ll xsz):raw(ysz,cdeq1<X>(xsz)){} cdeq1<X>& operator[](ll i) { return raw[i]; } X& operator[](ll j,ll i){ return raw[j][i]; } cdeq1<X>& back(){ return raw.back(); } auto begin(){ return raw.begin(); } auto end(){ return raw.end(); } cdeq1<X>& front(){ return raw.front(); } X pob(){ X ret=raw.back(); raw.pop_back(); return ret; } X pof(){ X ret=raw.front(); raw.pop_front(); return ret; } vo pub(X x){ raw.push_back(x); } vo puf(X x){ raw.push_front(x); } vo resize(ll n){ raw.resize(n); } auto size(){ return (ll)raw.size(); } }; template<class X>using cd=cdeq1<X>; using cdc=cd<ch>; using cdl=cd<ll>; using cds=cd<str>; using cdpall=cd<pall>; using cdtrlll=cd<trlll>; using cdqullll=cd<qullll>; template<class X>using cdd=cdeq2<X>; using cddl=cdd<ll>;
サンプル入力
int main() { cdl test1; fori(i,0,3) test1.pub(i); debugx(test1); debug(test1.pof()); debugx(test1); printen(); cddl test2(3,3); test2[1].pub(1); debugxy(test2); return 0; }
サンプル出力
test1[]=[0]0[1]1[2]2 test1.pof()=0 test1[]=[0]1[1]2 test2[0][]=[0]0[1]0[2]0 test2[1][]=[0]0[1]0[2]0[3]1 test2[2][]=[0]0[1]0[2]0
ist
template<template<class...>class TE, class TY>struct IST:std::false_type {}; template<template<class...>class TE, class...A>struct IST<TE,TE<A...>>:std::true_type {};
テンプレート引数が何のcollectionか取得したりするのに使う
ssort
void _ssort1(long long i, auto b, auto e) { sort(b,e,[&](auto& l, auto& r) { return (i==0)?l.a<r.a:l.b<r.b; }); } void _ssort2(long long i, auto b, auto e) { sort(b,e,[&](auto& l, auto& r) { return (i==0)?l.a<r.a:(i==1)?l.b<r.b:(l.c<r.c); }); } void _ssort3(long long i, auto b, auto e) { sort(b,e,[&](auto& l, auto& r) { return (i==0)?l.a<r.a:(i==1)?l.b<r.b:(i==2)?(l.c<r.c):l.d<r.d; }); } template<long long i>void ssort(auto b, auto e) { [&]<class T>(T x)->T { if constexpr(IST<pa,T>::value) _ssort1(i,b,e); else if constexpr(IST<tri,T>::value) _ssort2(i,b,e); else if constexpr(IST<quad,T>::value) _ssort3(i,b,e); else if constexpr(IST<pair,T>::value||IST<tuple,T>::value) sort(b,e,[&](auto& l, auto& r) { return std::get<i>(l)<std::get<i>(r); }); else sort(b,e,[&](auto& l, auto& r) { return boost::pfr::get<i>(l)<boost::pfr::get<i>(r); }); return x; }(*b); }
i番目のメンバ変数を比較して構造体をソートする
マクロ
for文に可変引数マクロのテクニックを利用
https://blog.miz-ar.info/2015/12/c-variadic-macro/
#define all(co) (co).begin(),(co).end() #define allr(co) (co).rbegin(),(co).rend() #define debug(...) { cerr<<"\033[32m"; cerr<<#__VA_ARGS__<<" = "; DEBUG(__VA_ARGS__); cerr<<"\033[m"; } #define debug1(co) { cerr<<#co<<"[] = "; fori(x,0,lsz(co),1) cerr<<'['<<x<<']'<<co[x]; DEBUG(); } #define debug2(co) fori(y,0,lsz(co),1) { cerr<<'['<<y<<']'<<sp; debug1(co[y]); } #define fori2(i,co) for(ll i=0;i<co.size();i++) #define fori3(i,b,e) for(ll i=b;i<e;i++) #define fori4(i,b,e,d) for(ll i=b;(0<d&&i<e)||(d<0&&e<i);i+=d) #define fori_args(a) overload4 a #define fori(...) fori_args((__VA_ARGS__,fori4,fori3,fori2,_))(__VA_ARGS__) #define forij3(i,j,co) fori(i,co) fori(j,co[0]) #define forij4(i,isz,j,jsz) fori(i,0,isz) fori(j,0,jsz) #define forij_args(a) overload4 a #define forij(...) fori_args((__VA_ARGS__,forij4,forij3,_,_))(__VA_ARGS__) #define forijk4(i,j,k,co) fori(i,co) fori(j,co[i]) fori(k,co[i][j]) #define forijk6(i,isz,j,jsz,k,ksz) fori(i,0,isz) fori(j,0,jsz) fori(k,0,ksz) #define forijk_args(a) overload6 a #define forijk(...) fori_args((__VA_ARGS__,forijk6,_,forijk4,_,_,_))(__VA_ARGS__) #define forx2(a,co) for(auto& a:co) #define forx3(a,b,co) for(auto& [a,b]:co) #define forx4(a,b,c,co) for(auto& [a,b,c]:co) #define forx5(a,b,c,d,co) for(auto& [a,b,c,d]:co) #define forx_args(a) overload5 a #define forx(...) forx_args((__VA_ARGS__,forx5,forx4,forx3,forx2,_))(__VA_ARGS__) #define forxy2(a,co) for(auto& y:co) for(auto& a:y) #define forxy3(a,b,co) for(auto& y:co) for(auto& [a,b]:y) #define forxy4(a,b,c,co) for(auto& y:co) for(auto& [a,b,c]:y) #define forxy5(a,b,c,d,co) for(auto& y:co) for(auto& [a,b,c,d]:y) #define forxy_args(a) overload5 a #define forxy(...) forxy_args((__VA_ARGS__,forxy5,forxy4,forxy3,forxy2,_))(__VA_ARGS__) #define forxyz2(a,co) for(auto& z:co) for(auto& y:z) for(auto& a:y) #define forxyz3(a,b,co) for(auto& z:co) for(auto& y:z) for(auto& [a,b]:y) #define forxyz4(a,b,c,co) for(auto& z:co) for(auto& y:z) for(auto& [a,b,c]:y) #define forxyz5(a,b,c,d,co) for(auto& z:co) for(auto& y:z) for(auto& [a,b,c,d]:y) #define forxyz_args(a) overload5 a #define forxyz(...) forxyz_args((__VA_ARGS__,forxyz5,forxyz4,forxyz3,forxyz2,_))(__VA_ARGS__) #define inch(...) ch __VA_ARGS__; IN(__VA_ARGS__); #define indl(name,sz) dl name(sz); IN(name); #define infl(...) ld __VA_ARGS__; IN(__VA_ARGS__); #define inll(...) ll __VA_ARGS__; IN(__VA_ARGS__); #define inspll2(name,sz) spll name; IN_DIM1P(name,sz) #define inspll4(name,sz,dx,dy) spll name; IN_DIM1P(name,sz,ll(dx),ll(dy)) #define inspll_overload(a,b,c,d,x,...) x #define inspll_args(a) inspll_overload a #define inspll(...) inspll_args((__VA_ARGS__,inspll4,_,inspll2,_))(__VA_ARGS__) #define instr(...) str __VA_ARGS__; IN(__VA_ARGS__); #define incvl(name,sz) cvl name(sz); forx(x,name) cin>>x; #define incvs(name,sz) cvs name(sz); forx(x,name) cin>>x; #define incvvl(name,ysz,xsz) vvl name(ysz,xsz); forx(y,name) forx(x,y) cin>>x; #define invvc3(name,ysz,xsz) vvc name(ysz,xsz); forx(y,name) forx(x,y) cin>>x; #define invvc4(name,ysz,xsz,diff) vvc name(ysz,xsz); forx(y,name) forx(x,y) cin>>x,x+=diff; #define invvc_args(a) overload4 a #define invvc(...) invvc_args((__VA_ARGS__,invvc4,invvc3,_,_))(__VA_ARGS__) #define invpll2(name,sz) vpll name(sz); forx(x,y,name) INP(x,y); #define invpll4(name,sz,dx,dy) vpll name(sz); forx(x,y,name) INP(x,y,dx,dy); #define invpllargs(a) overload4 a #define invpll(...) invpllargs((__VA_ARGS__,invpll4,_,invpll2,_))(__VA_ARGS__) #define in_graph(name,vsz,esz,vifix) graph name(vsz); ING(name,esz,vifix); #define in_directed_graph(name,vsz,esz,vifix) graph name(vsz); INDG(name,esz,vifix); #define in_weighted_graph(name,vsz,esz,vifix) graph name(ndsz); INWG(name,esz,vifix); #define in_weighted_directed_graph(name,vsz,esz,vifix) graph name(vsz); INWDG(name,esz,vifix); #define lam(f,ret,...) auto f=[&](__VA_ARGS__)->ret #define lamt(f,ret,...) auto f=[&]<class T>(__VA_ARGS__)->ret #define lamtu(f,ret,...) auto f=[&]<class T, class U>(__VA_ARGS__)->ret #define lamtuv(f,ret,...) auto f=[&]<class T, class U, class V>(__VA_ARGS__)->ret #define overload1(a,z,...) z #define overload2(a,b,z,...) z #define overload3(a,b,c,z,...) z #define overload4(a,b,c,d,z,...) z #define overload5(a,b,c,d,e,z,...) z #define overload6(a,b,c,d,e,f,z,...) z
関数
- at
ll at(auto& c, ll i){ return i<0?lsz(c)+i+abs(abs(i+1)/lsz(c))*lsz(c):i-(i/lsz(c))*lsz(c); } ll atr(auto& c, ll i){ return i<0?(abs(i)-1)-((abs(i)-1)/lsz(c))*lsz(c):lsz(c)-1-(i-(i/lsz(c))*lsz(c)); }
pythonを参考にコレクションを負のインデックスで取得出来るようにした関数
- bit
ll bitcnt(ll x, ll b){ return (b)?popcount(ull(x)):llog_ceil(2,x)-popcount(ull(x)); } bo bitget(ll x, ll i){ return (62<i)?0:bo(x&(1ll<<i)); } ll bitlen(ll x){ return !x?1:llog(2,x)+1; } vo bitud(ll& x, ll i, ll y){ (y)?x|=(1ll<<i):x&=~(1ll<<i); }
- deg
vl degin(graph& g) { vl deg(lsz(g)); fori(i,0,lsz(g)) for(auto& [vj,ey]:g[i]) deg[vj]++; return deg; } vl degout(graph& g) { vl deg(lsz(g)); fori(i,0,lsz(g)) deg[i]+=lsz(g[i]); return deg; }
vl degin(graph& g); グラフの全頂点の入次数を返す
vl degout(graph& g); グラフの全頂点の出次数を返す
- ll
template <class C> ll lcnt(C& c) { return ll(c.count()); } template <class C, class X> ll lcnt(C& c, X x) { return ll(count(all(c),x)); } ll ldivc(ll a,ll b) { return (a+b-1)/b; } ll ldivf(ll a,ll b) { return a/b; } template<class C>ll lfind(C& c, auto x) { if constexpr(is_same_v<st,C>) return (c.find(x)==st::npos)?0:1; else return (c.find(x)==c.end())?0:1; } ll llogc(ll a,ll b) { ll res=0; for(ll i=1;i<b;res++) i*=a; return res; } ll llogf(ll a,ll b) { ll res=0; for(ll i=1;i<=b;res++) i*=a; return res-1; } ll lpow(ll x, ll n) { if(n<0) return 0; if(x==2) return (1ll<<n); ll z=1; fori(i,0,n) z*=x; return z; } ll lsz(auto& t){ return (ll)t.size(); } ll llen(ll x){ return (ll)tostr(x).size(); }
out
vo outen(au head, au...tail) { cout<<fixed<<setprecision(10)<<head<<'\n'; outen(tail...); } vo outen(au tail) { cout<<fixed<<setprecision(10)<<tail; exit(0); } vo outsp(au head, au...tail) { cout<<fixed<<setprecision(10)<<head<<' '; outsp(tail...); } vo outsp(au tail) { cout<<fixed<<setprecision(10)<<tail; exit(0); } vo out1en(au& c) { cout<<fixed<<setprecision(10); forx(x,c) cout<<x<<'\n'; exit(0); } vo out1sp(au& c) { cout<<fixed<<setprecision(10); forx(x,c) cout<<x<<' '; exit(0); } vo out2(au& c) { forx(x,c) cout1sp(x),couten(); exit(0); }
副作用のある(複雑な)使い方は未規定なので注意
map<ll,ll> m1,m2; m1[1]++,m1[2]++,m1[3]++,m2[1]++,m2[2]++,m2[3]++; auto f=[&](map<ll,ll>& m) { m.erase(1); return m.begin()->first; }; auto g=[&](map<ll,ll>& m) { m.erase(2); return m.begin()->first; }; auto a=f(m1); auto b=g(m1); outen(a,b,f(m2),g(m2));
上記サンプルコードを実行すると以下が出力されてしまう
2 3 3 1
参考 https://www.jpcert.or.jp/sc-rules/c-exp30-c.html
void print(){ cout<<en; } template<class H, class...T>void print(H head, T ... tail){ cout<<fixed<<setprecision(8)<<head<<sp; print(tail...); }
- to
ch toch(ll x) { return ch(x+48); } st tostr(ll x) { return to_string(x); } ll toll(ch c) { return ll(c)-48; } ll toll(st& s) { return stoll(s); } st tolower(const st& s){ st res; forx(x,s) pushb(res,tolower(x)); return res; } st toupper(const st& s){ st res; forx(x,s) pushb(res,toupper(x)); return res; }
- orange
bo orange(ll x, auto& c) { return x<0&&lsz(c)<=x; } bo orange(ll y, ll x, auto& c) { return y<0||lsz(c)<=y||x<0||lsz(c[y])<=x; }
- IN
void IN(){} template<class H, class ... T>void IN(H& head, T& ... tail){ cin>>head; IN(tail...); } template<class T, class U>void IN(tup<T,U>& t){ cin>>ta(t)>>tb(t); } template<class T>void IN(de<T>& c) { forx(e,c) IN(e); } template<class T>void IN(ve<T>& c) { forx(x,c) IN(x); } vo INVT(auto& v, auto afix, auto bfix){ forx(a,b,v) IN(a,b),a+=afix,b+=bfix; } vo ING(graph& g, ll esz, ll vifix) { ll vi,nvi; fori(e,0,esz) cin>>vi>>nvi,pushb(g[vi+vifix],edge{nvi+vifix,1}),pushb(g[nvi+vifix],edge{vi+vifix,1}); } vo INDG(graph& g, ll edsz, ll ndfix) { fori(e,0,edsz) { ll i,j; cin>>i>>j,i+=ndfix,j+=ndfix,g[i].push_back({j,1});} } vo INWG(graph& g, ll edsz, ll ndfix) { fori(e,0,edsz) { ll i,j,c; cin>>i>>j>>c,i+=ndfix,j+=ndfix,g[i].push_back({j,c}),g[j].push_back({i,c}); } } vo INWDG(graph& g,ll edsz,ll ndfix) { fori(e,0,edsz) { ll i,j,c; cin>>i>>j>>c,i+=ndfix,j+=ndfix,g[i].push_back({j,c}); } }
最近流行ってるらしく多くの人がテンプレとして用意している
pythonのように変数宣言と入力を同時に可能にした関数でマクロから呼び出す
- IST
template<template<class...>class TE, class TY>struct IST:std::false_type {}; template<template<class...>class TE, class...A>struct IST<TE,TE<A...>>:std::true_type {};
constexpr if文で使う
コード
#define AT_CODER #ifdef AT_CODER #include <atcoder/all> #endif #define BOOST #ifdef BOOST #pragma warning(disable: 4996) #include <boost/dynamic_bitset.hpp> #include <boost/multiprecision/cpp_dec_float.hpp> #include <boost/multiprecision/cpp_int.hpp> #include <boost/pfr.hpp> using bit=boost::dynamic_bitset<>; using mi=boost::multiprecision::cpp_int; using mf=boost::multiprecision::cpp_dec_float_100; #endif import std; using namespace std; const char en='\n'; const long long inf=2000000000000000000; const long long maxll=9223372036854775807; const long long maxabc=26; const long long mod1=1000000007; const long long mod9=998244353; const double pi=3.141592653589; const char sp=' '; using bo=bool; using ch=char; using ll=long long; using vo=void; using uni=unsigned int; using unll=unsigned long long; template<class A,class B>struct pa{ pair<A,B> raw; auto operator<=>(const pa&)const=default; pa(){} pa(A a,B b):raw(a,b){} pa(pair<A,B> p):raw(p){} auto operator()(ll i){ return(i==0)?raw.first:raw.second; } pa& operator=(const pa& r){ raw=r.raw; return *this; } pa operator+(const pa& r){ pa ret(raw); ret+=r; return ret; } pa operator-(const pa& r){ pa ret(raw); ret-=r; return ret; } pa operator*(const pa& r){ pa ret(raw); ret*=r; return ret; } pa operator/(const pa& r){ pa ret(raw); ret/=r; return ret; } pa& operator+=(const pa& r){ raw.first+=r.raw.first,raw.second+=r.raw.second; return *this; } pa& operator-=(const pa& r){ raw.first-=r.raw.first,raw.second-=r.raw.second; return *this; } pa& operator*=(const pa& r){ raw.first*=r.raw.first,raw.second*=r.raw.second; return *this; } pa& operator/=(const pa& r){ raw.first/=r.raw.first,raw.second/=r.raw.second; return *this; } }; template<class A,class B,class C>struct tr{ tuple<A,B,C> raw; auto operator<=>(const tr&)const=default; tr(){} tr(A a,B b,C c):raw(a,b,c){} tr(tuple<A,B,C> t):raw(t){} auto operator()(ll i){ return(i==0)?get<0>(raw):(i==1)?get<1>(raw):get<2>(raw); } tr operator+(const tr& r){ tr ret(raw); ret+=r; return ret; } tr operator-(const tr& r){ tr ret(raw); ret-=r; return ret; } tr operator*(const tr& r){ tr ret(raw); ret*=r; return ret; } tr operator/(const tr& r){ tr ret(raw); ret/=r; return ret; } tr& operator+=(const tr& r){ get<0>(raw)+=get<0>(r.raw),get<1>(raw)+=get<1>(r.raw),get<2>(raw)+=get<2>(r.raw); return *this; } tr& operator-=(const tr& r){ get<0>(raw)-=get<0>(r.raw),get<1>(raw)-=get<1>(r.raw),get<2>(raw)-=get<2>(r.raw); return *this; } tr& operator*=(const tr& r){ get<0>(raw)*=get<0>(r.raw),get<1>(raw)*=get<1>(r.raw),get<2>(raw)*=get<2>(r.raw); return *this; } tr& operator/=(const tr& r){ get<0>(raw)/=get<0>(r.raw),get<1>(raw)/=get<1>(r.raw),get<2>(raw)/=get<2>(r.raw); return *this; } }; template<class A,class B,class C,class D>struct qu{ tuple<A,B,C,D> raw; auto operator<=>(const qu&)const=default; qu(){} qu(A a,B b,C c,D d):raw(a,b,c,d){} qu(tuple<A,B,C,D> q):raw(q){} auto operator()(ll i){ return(i==0)?get<0>(raw):(i==1)?get<1>(raw):(i==2)?get<2>(raw):get<3>(raw); } qu operator+(const qu& r){ qu ret(raw); ret+=r; return ret; } qu operator-(const qu& r){ qu ret(raw); ret-=r; return ret; } qu operator*(const qu& r){ qu ret(raw); ret*=r; return ret; } qu operator/(const qu& r){ qu ret(raw); ret/=r; return ret; } qu& operator+=(const qu& r){ get<0>(raw)+=get<0>(r.raw),get<1>(raw)+=get<1>(r.raw),get<2>(raw)+=get<2>(r.raw),get<3>(raw)+=get<3>(r.raw); return *this; } qu& operator-=(const qu& r){ get<0>(raw)-=get<0>(r.raw),get<1>(raw)-=get<1>(r.raw),get<2>(raw)-=get<2>(r.raw),get<3>(raw)-=get<3>(r.raw); return *this; } qu& operator*=(const qu& r){ get<0>(raw)*=get<0>(r.raw),get<1>(raw)*=get<1>(r.raw),get<2>(raw)*=get<2>(r.raw),get<3>(raw)*=get<3>(r.raw); return *this; } qu& operator/=(const qu& r){ get<0>(raw)/=get<0>(r.raw),get<1>(raw)/=get<1>(r.raw),get<2>(raw)/=get<2>(r.raw),get<3>(raw)/=get<3>(r.raw); return *this; } }; struct str { string raw; str(){} str(const string& s):raw(s){} str& operator=(const string& s){ raw=s; return *this; } auto& operator[](ll i) { return raw[i]; } auto back() { return raw.back(); } auto begin() { return raw.begin(); } auto end() { return raw.end(); } bo find(string s) { return raw.find(s)!=string::npos; }ch pob(auto& x) { ch res=raw.back(); raw.pop_back(); return res; } vo pub(auto& x) { raw.push_back(x); } vo resize(ll n) { raw.resize(n); } ll size(){ return (ll)raw.size(); } }; template<class X>struct cvec1{ vector<X> raw; cvec1(){} cvec1(ll xsz):raw(xsz){} cvec1(ll xsz,X init):raw(xsz,init){} auto& operator[](ll i){ return raw[i]; } auto back(){ return raw.back(); } auto begin(){ return raw.begin(); } auto end(){ return raw.end(); } auto pob(){ auto res=raw.back(); raw.pop_back(); return res; } vo pub(auto& x){ raw.push_back(x); } vo resize(ll n){ raw.resize(n); } auto size(){ return (ll)raw.size(); } }; template<class X>struct cvec2{ vector<cvec1<X>> raw; cvec2(ll ysz,ll xsz):raw(ysz,cvec1<X>(xsz)){} cvec2(ll ysz,ll xsz,X init):raw(ysz,cvec1<X>(xsz,init)){} auto& operator[](ll i){ return raw[i]; } auto& operator[](ll j,ll i){ return raw[j][i]; } auto back(){ return raw.back(); } auto begin(){ return raw.begin(); } auto end(){ return raw.end(); } auto pob(){ auto res=raw.back(); raw.pop_back(); return res; } vo pub(auto& x){ raw.push_back(x); } vo resize(ll n){ raw.resize(n); } auto size(){ return (ll)raw.size(); } }; template<class X>struct cvec3{ vector<cvec2<X>> raw; cvec3(ll zsz,ll ysz,ll xsz):raw(zsz,cvec2<X>(ysz,xsz)){} cvec3(ll zsz,ll ysz,ll xsz,X init):raw(zsz,covec2<X>(ysz,xsz,init)){} auto& operator[](ll i){ return raw[i]; } auto& operator[](ll j,ll i){ return raw[j][i]; } auto& operator[](ll k,ll j,ll i){ return raw[k][j][i]; } auto back(){ return raw.back(); } auto begin(){ return raw.begin(); } auto end(){ return raw.end(); } auto pob(){ auto res=raw.back(); raw.pop_back(); return res; } vo pub(auto& x){ raw.push_back(x); } vo resize(ll n){ raw.resize(n); } auto size(){ return (ll)raw.size(); } }; template<class X>struct codeq1 { deque<X> raw; codeq1(){} codeq1(ll xsz):raw(xsz) {} auto& operator[](ll i) { return raw[i]; } auto back() { return raw.back(); } auto begin() { return raw.begin(); } auto end() { return raw.end(); } vo pob() { raw.pop_back(); } vo pub(auto x) { raw.push_back(x); } vo resize(ll n) { raw.resize(n); } auto size(){ return (ll)raw.size(); } }; template<class X>struct codeq2 { deque<codeq1<X>> raw; codeq2(){} codeq2(ll ysz,ll xsz):raw(ysz,codeq1<X>(xsz)){} auto& operator[](ll i) { return raw[i]; } auto back() { return raw.back(); } auto begin() { return raw.begin(); } auto end() { return raw.end(); } vo pob() { raw.pop_back(); } vo pub(auto x) { raw.push_back(x); } vo resize(ll n) { raw.resize(n); } auto size(){ return (ll)raw.size(); } }; template<class K, class X>struct cmap { map<K,X> raw; ll& operator[](K k) { return raw[k]; } auto begin_ls() { return raw.rbegin(); } auto begin_sl() { return raw.begin(); } auto end_ls() { return raw.rbegin(); } auto end_sl() { return raw.end(); } vo erase(K k) { raw.erase(k); } bo find(K k) { return raw.find(k)!=raw.end(); } X get(K k) { return find(k)?raw[k]:X(); } ll lsz() { return raw.size(); } K max_key() { return raw.rbegin()->first; } K min_key() { return raw.begin()->first; } vo set(K k, X x) { raw[k]=x; } }; template<class X>struct cset { set<X> raw; // TODO }; using pall=pa<ll,ll>; using trlll=tr<ll,ll,ll>; using qullll=qu<ll,ll,ll,ll>; template<class X>using cd=codeq1<X>; using cdc=cd<ch>; using cdl=cd<ll>; using cds=cd<str>; using cdpall=cd<pall>; using cdtrlll=cd<trlll>; using cdqullll=cd<qullll>; template<class K, class X>using cm=cmap<K,X>; using cmcl=cm<ch,ll>; using cmll=cm<ll,ll>; using cmsl=cm<str,ll>; template<class X>using cs=cset<X>; using csc=cs<ch>; using csl=cs<ll>; using css=cs<str>; using cspall=cs<pall>; using cstrlll=cs<trlll>; using csqullll=cs<qullll>; template<class X>using cv=cvec1<X>; using cvc=cv<ch>; using cvl=cv<ll>; using cvs=cv<str>; using cvpall=cv<pall>; using cvtrlll=cv<trlll>; using cvqullll=cv<qullll>; template<class X>using cvv=cvec2<X>; using cvvl=cvv<ll>; template<class X>using cvvv=cvec3<X>; using cvvvl=cvvv<ll>; template<class X=ll>struct edge{ ll to; X ex; }; template<class V,class E>struct vertex{ cv<edge<E>> e; V vx; auto& operator[](ll i){ return e[i]; } }; template<class V,class E>struct graph{ graph(ll vsz,ll esz):v(vsz){} cv<vertex<V,E>> v; auto& operator[](ll i){ return v[i]; } auto& operator[](ll i, ll j){ return v[i][j]; } }; template<template<class...>class T, class U>struct ist:std::false_type {}; template<template<class...>class T, class...U>struct ist<T,T<U...>>:std::true_type {}; #define all(co) (co).begin(),(co).end() #define allr(co) (co).rbegin(),(co).rend() #define debug(...) { cerr<<"\033[32m"; cerr<<#__VA_ARGS__<<" = "; DEBUG(__VA_ARGS__); cerr<<sp<<en<<"\033[m"; } #define debug1(co) { cerr<<#co<<"[] = "; fori(x,0,lsz(co),1) cerr<<'['<<x<<']'<<co[x]; DEBUG(); } #define debug2(co) fori(y,0,lsz(co),1) { cerr<<'['<<y<<']'<<sp; debug1(co[y]); } #define fori2(i,co) for(ll i=0;i<co.size();i++) #define fori3(i,b,e) for(ll i=b;i<e;i++) #define fori4(i,b,e,d) for(ll i=b;(0<d&&i<e)||(d<0&&e<i);i+=d) #define fori_args(a) overload4 a #define fori(...) fori_args((__VA_ARGS__,fori4,fori3,fori2,_))(__VA_ARGS__) #define forij3(i,j,co) fori(i,co) fori(j,co[0]) #define forij4(i,isz,j,jsz) fori(i,0,isz) fori(j,0,jsz) #define forij_args(a) overload4 a #define forij(...) fori_args((__VA_ARGS__,forij4,forij3,_,_))(__VA_ARGS__) #define forijk4(i,j,k,co) fori(i,co) fori(j,co[i]) fori(k,co[i][j]) #define forijk6(i,isz,j,jsz,k,ksz) fori(i,0,isz) fori(j,0,jsz) fori(k,0,ksz) #define forijk_args(a) overload6 a #define forijk(...) fori_args((__VA_ARGS__,forijk6,_,forijk4,_,_,_))(__VA_ARGS__) #define forx2(a,co) for(auto& a:co) #define forx3(a,b,co) for(auto& [a,b]:co) #define forx4(a,b,c,co) for(auto& [a,b,c]:co) #define forx5(a,b,c,d,co) for(auto& [a,b,c,d]:co) #define forx_args(a) overload5 a #define forx(...) forx_args((__VA_ARGS__,forx5,forx4,forx3,forx2,_))(__VA_ARGS__) #define forxy2(a,co) for(auto& y:co) for(auto& a:y) #define forxy3(a,b,co) for(auto& y:co) for(auto& [a,b]:y) #define forxy4(a,b,c,co) for(auto& y:co) for(auto& [a,b,c]:y) #define forxy5(a,b,c,d,co) for(auto& y:co) for(auto& [a,b,c,d]:y) #define forxy_args(a) overload5 a #define forxy(...) forxy_args((__VA_ARGS__,forxy5,forxy4,forxy3,forxy2,_))(__VA_ARGS__) #define forxyz2(a,co) for(auto& z:co) for(auto& y:z) for(auto& a:y) #define forxyz3(a,b,co) for(auto& z:co) for(auto& y:z) for(auto& [a,b]:y) #define forxyz4(a,b,c,co) for(auto& z:co) for(auto& y:z) for(auto& [a,b,c]:y) #define forxyz5(a,b,c,d,co) for(auto& z:co) for(auto& y:z) for(auto& [a,b,c,d]:y) #define forxyz_args(a) overload5 a #define forxyz(...) forxyz_args((__VA_ARGS__,forxyz5,forxyz4,forxyz3,forxyz2,_))(__VA_ARGS__) #define inch(...) ch __VA_ARGS__; IN(__VA_ARGS__); #define indl(name,sz) dl name(sz); IN(name); #define infl(...) ld __VA_ARGS__; IN(__VA_ARGS__); #define inll(...) ll __VA_ARGS__; IN(__VA_ARGS__); #define inspll2(name,sz) spll name; IN_DIM1P(name,sz) #define inspll4(name,sz,dx,dy) spll name; IN_DIM1P(name,sz,ll(dx),ll(dy)) #define inspll_overload(a,b,c,d,x,...) x #define inspll_args(a) inspll_overload a #define inspll(...) inspll_args((__VA_ARGS__,inspll4,_,inspll2,_))(__VA_ARGS__) #define instr(...) str __VA_ARGS__; IN(__VA_ARGS__); #define incvl(name,sz) cvl name(sz); forx(x,name) cin>>x; #define incvs(name,sz) cvs name(sz); forx(x,name) cin>>x; #define incvvl(name,ysz,xsz) vvl name(ysz,xsz); forx(y,name) forx(x,y) cin>>x; #define invvc3(name,ysz,xsz) vvc name(ysz,xsz); forx(y,name) forx(x,y) cin>>x; #define invvc4(name,ysz,xsz,diff) vvc name(ysz,xsz); forx(y,name) forx(x,y) cin>>x,x+=diff; #define invvc_args(a) overload4 a #define invvc(...) invvc_args((__VA_ARGS__,invvc4,invvc3,_,_))(__VA_ARGS__) #define invpll2(name,sz) vpll name(sz); forx(x,y,name) INP(x,y); #define invpll4(name,sz,dx,dy) vpll name(sz); forx(x,y,name) INP(x,y,dx,dy); #define invpllargs(a) overload4 a #define invpll(...) invpllargs((__VA_ARGS__,invpll4,_,invpll2,_))(__VA_ARGS__) #define in_graph(name,vsz,esz,vifix) graph name(vsz); ING(name,esz,vifix); #define in_directed_graph(name,vsz,esz,vifix) graph name(vsz); INDG(name,esz,vifix); #define in_weighted_graph(name,vsz,esz,vifix) graph name(ndsz); INWG(name,esz,vifix); #define in_weighted_directed_graph(name,vsz,esz,vifix) graph name(vsz); INWDG(name,esz,vifix); #define lam(f,ret,...) auto f=[&](__VA_ARGS__)->ret #define lamt(f,ret,...) auto f=[&]<class T>(__VA_ARGS__)->ret #define lamtu(f,ret,...) auto f=[&]<class T, class U>(__VA_ARGS__)->ret #define lamtuv(f,ret,...) auto f=[&]<class T, class U, class V>(__VA_ARGS__)->ret #define overload1(a,z,...) z #define overload2(a,b,z,...) z #define overload3(a,b,c,z,...) z #define overload4(a,b,c,d,z,...) z #define overload5(a,b,c,d,e,z,...) z #define overload6(a,b,c,d,e,f,z,...) z auto& atb(auto& co, ll i, ll mod=1); auto& atf(auto& co, ll i, ll mod=1); ll bitcnt(ll x, bo b); bo bitget(ll x, ll i); ll bitsz(ll x); vo bitoff(ll& x, ll i); vo biton(ll& x, ll i); ll ldiv(ll a, ll b); ll ldiv_ceil(ll a, ll b); ll llog(ll a, ll b); ll llog_ceil(ll a, ll b); ll lpow(ll x, ll n); vo outen(auto head, auto...tail); vo outen(auto tail); vo outsp(auto head, auto...tail); vo outsp(auto tail); vo outspx(auto& co); vo outxy(auto& co); vo printen(auto head, auto...tail); vo printen(auto tail); vo printsp(auto head, auto...tail); vo printsp(auto tail); vo printspx(auto& c); vo printenx(auto& c); auto pob(auto& a); auto pof(auto& a); auto pomax(auto& a); auto pomin(auto& a); vo pub(auto& a, auto x); vo puf(auto& a, auto x); str tostr(ll x); vo DEBUG(auto x); template<class H, class...T>vo DEBUG(H h, T...t); void IN(); template<class H, class...T>vo IN(H& head, T&...tail); vo INP(auto& x, auto& y); auto& atb(auto& co, ll i, ll mod) { return co[lsz(co)-1-i%mod]; } auto& atf(auto& co, ll i, ll mod) { return co[i%mod]; } ll bitcnt(ll x, bo b){ return (b)?popcount((unsigned long long)x):bit_width((unsigned long long)x)-popcount((unsigned long long)x); } bo bitget(ll x, ll i){ return (62<i)?0:bo(x&(1ll<<i)); } ll bitsz(ll x) { return bit_width((unsigned long long)x); } vo bitoff(ll& x, ll i){ x|=(1ll<<i); } vo biton(ll& x, ll i){ x&=~(1ll<<i); } template <class C> ll lcnt(C& c) { return ll(c.count()); } template <class C, class X> ll lcnt(C& c, X x) { return ll(count(all(c),x)); } ll ldiv(ll a, ll b) { return a/b; } ll ldiv_ceil(ll a, ll b) { return (a+b-1)/b; } ll llog(ll a, ll b) { ll res=0; for(ll i=1;i<=b;res++) i*=a; return res-1; } ll llog_ceil(ll a, ll b) { ll res=0; for(ll i=1;i<b;res++) i*=a; return res; } ll lpow(ll x, ll n) { if(n<0) return 0; if(x==2) return (1ll<<n); ll z=1; fori(i,0,n,1) z*=x; return z; } ll llen(ll x){ return llog(10,x)+1; } vo itox(auto& c) { fori(i,0,lsz(c),1) c[i]=i; } auto pob(auto& co) { auto r=co.back(); co.pop_back(); return r;} auto pof(auto& co) { auto r=co.front(); co.pop_front(); return r; } auto pomax(auto& co) { return (co.front()>=co.back())?pof(co):pob(co); } auto pomin(auto& co) { return (co.front()<=co.back())?pof(co):pob(co); } vo pub(auto& co, auto x) { co.pub(x); } vo puf(auto& co, auto x) { co.puf(x); } ch toch(ll x) { return ch(x+48); } str tostr(ll x) { return str(to_string(x)); } ll toll(ch c) { return ll(c)-48; } ll toll(str& s) { return stoll(s.raw); } ch tocc(ch c) { return c^=0x20; } str tocc(str& s){ str res; forx(x,s) pub(res,tocc(x)); return res; } cvc tocvc(str& s) { cvc res; forx(x,s) pub(res,x); return res; } bo orange(auto& c, ll x) { return x<0||lsz(c)<=x; } bo orange(auto& c, ll y, ll x) { return y<0||lsz(c)<=y||x<0||lsz(c[y])<=x; } vo outen(auto head, auto...tail) { cout<<fixed<<setprecision(10)<<head<<en; outen(tail...); } vo outen(auto tail) { cout<<fixed<<setprecision(10)<<tail; exit(0); } vo outenx(auto& co){ cout<<fixed<<setprecision(10); forx(x,co) cout<<x<<en; exit(0); } vo outsp(auto head, auto...tail) { cout<<fixed<<setprecision(10)<<head<<sp; outsp(tail...); } vo outsp(auto tail) { cout<<fixed<<setprecision(10)<<tail; exit(0); } vo outspx(auto& co){ cout<<fixed<<setprecision(10); forx(x,co) cout<<x<<sp; exit(0); } vo outxy(auto& co){ cout<<fixed<<setprecision(10); forx(y,co) printspx(y),cout<<en; exit(0); } vo printen(auto head, auto...tail) { cout<<fixed<<setprecision(10)<<head<<en; printen(tail...); } vo printen(auto tail) { cout<<fixed<<setprecision(10)<<tail<<en; } vo printenx(auto& c) { cout<<fixed<<setprecision(10); forx(x,c) cout<<x<<en; } vo printsp(auto head, auto...tail) { cout<<fixed<<setprecision(10)<<head<<' '; printsp(tail...); } vo printsp(auto tail) { cout<<fixed<<setprecision(10)<<tail<<en; } vo printspx(auto& c) { cout<<fixed<<setprecision(10); forx(x,c) cout<<x<<sp; } vo sortls(auto& x, auto& y) { if(y>x) swap(y,x); } vo sortls(auto& x, auto& y, auto& z) { if(z>y) swap(z,y); if(y>x) swap(y,x); if(z>y) swap(z,y); } vo sortsl(auto& x, auto& y) { if(x>y) swap(x,y); } vo sortsl(auto& x, auto& y, auto& z) { if(x>y) swap(x,y); if(y>z) swap(y,z); if(y>x) swap(x,y); } template <class T> T trim(T& c, ll l, ll r) { T t=T(); umin(r,lsz(c)); fori(i,l,r,1) push(t,c[i]); return t; } template <class T1, class ... T2> bool umax(T1& x, T2 ... args) { x=max({x,args...}); return !(max({args...})<x); } template <class T1, class ... T2> bool umin(T1& x, T2 ... args) { x=min({x,args...}); return !(x<min({args...}));} vo DEBUG(auto x) { cerr<<x; } template<class H, class ... T>vo DEBUG(H h, T ... t){ cerr<<fixed<<setprecision(8)<<h<<','; DEBUG(t...); } void IN(){} template<class H, class ... T>vo IN(H& head, T& ... tail){ cin>>head; IN(tail...); } template<class A, class X, class Y>vo IN_DIM1P(A& a, ll sz) { pair<X,Y> p; if constexpr(ist<cv,A>::value||ist<cd,A>::value) while(sz--) IN_P(p),pub(a,p); else while(sz--) IN_P(p),push(a,p); } template<class X, class Y>vo IN_DIM1P(auto& a, ll sz, X dx, Y dy) { pair<X,Y> p; if(IS_PUSH(a)) while(sz--) IN_P(p),p.first+=dx,p.second+=dy,push(a,p); else while(sz--) IN_P(p),p.first+=dx,p.second+=dy,pub(a,p); } vo INP(auto& x, auto& y) { cin>>x>>y; } vo INP(auto& x, auto& y, auto dx, auto dy) { cin>>x>>y,x+=dx,y+=dy; } //vo ING(graph<ll,ll>& g, ll esz, ll fix) { ll fr,to; fori(e,0,esz,1) cin>>fr>>to,fr+=fix,to+=fix,g(fr).e.pub(edge{0ll,to}),pub(g[to].e,edge{0ll,fr}); } //vo INDG(graph<ll,ll>& g, ll esz, ll fix) { ll fr,to; fori(e,0,esz,1) cin>>fr>>to,fr+=fix,to+=fix,pub(g[fr].e,edge{0ll,to}); } //vo INWG(graph<ll,ll>& g, ll esz, ll fix) { ll fr,to,c; fori(e,0,esz,1) cin>>fr>>to>>c,fr+=fix,to+=fix,pub(g[fr].e,edge{c,to}),pub(g[to].e,edge{c,fr}); } //vo INWDG(graph<ll,ll>& g,ll esz,ll fix) { ll fr,to,c; fori(e,0,esz,1) cin>>fr>>to>>c,fr+=fix,to+=fix,pub(g[fr].e,edge{c,to}); } #ifdef BOOST vo BOOST_SORT1(ll i, auto b, auto e) { sort(b,e,[&](auto& l, auto& r) { return (i==0)?l.a<r.a:l.b<r.b; }); } vo BOOST_SORT2(ll i, auto b, auto e) { sort(b,e,[&](auto& l, auto& r) { return (i==0)?l.a<r.a:(i==1)?l.b<r.b:(l.c<r.c); }); } vo BOOST_SORT3(ll i, auto b, auto e) { sort(b,e,[&](auto& l, auto& r) { return (i==0)?l.a<r.a:(i==1)?l.b<r.b:(i==2)?(l.c<r.c):l.d<r.d; }); } template<ll i>vo boost_sort(auto b, auto e) { [&]<class T>(T x)->T { if constexpr(ist<pa,T>::value) BOOST_SORT1(i,b,e); else if constexpr(ist<tr,T>::value) BOOST_SORT2(i,b,e); else if constexpr(ist<qu,T>::value) BOOST_SORT3(i,b,e); else if constexpr(ist<pair,T>::value||ist<tuple,T>::value) sort(b,e,[&](auto& l, auto& r) { return std::get<i>(l)<std::get<i>(r); }); else sort(b,e,[&](auto& l, auto& r) { return boost::pfr::get<i>(l)<boost::pfr::get<i>(r); }); return x; }(*b); } #endif /*************************************/ /********** END OF TEMPLATE **********/ /*************************************/