#pragma once
#include<cassert>
#include<numeric>
#include<vector>usingnamespacestd;#include"../internal/internal-type-traits.hpp"
#include"../math-fast/gcd.hpp"// T : 値, U : 比較用template<typenameT,typenameU>structRationalBase{usingR=RationalBase;usingKey=T;Tx,y;RationalBase():x(0),y(1){}template<typenameT1>RationalBase(constT1&_x):RationalBase<T,U>(_x,T1{1}){}template<typenameT1,typenameT2>RationalBase(constpair<T1,T2>&_p):RationalBase<T,U>(_p.first,_p.second){}template<typenameT1,typenameT2>RationalBase(constT1&_x,constT2&_y):x(_x),y(_y){assert(y!=0);if(y==-1)x=-x,y=-y;if(y!=1){Tg;ifconstexpr(internal::is_broadly_integral_v<T>){ifconstexpr(sizeof(T)==16){g=binary_gcd128(x,y);}else{g=binary_gcd(x,y);}}else{g=gcd(x,y);}if(g!=0)x/=g,y/=g;if(y<0)x=-x,y=-y;}}// y = 0 の代入も認めるstaticRraw(T_x,T_y){Rr;r.x=_x,r.y=_y;returnr;}friendRoperator+(constR&l,constR&r){if(l.y==r.y)returnR{l.x+r.x,l.y};returnR{l.x*r.y+l.y*r.x,l.y*r.y};}friendRoperator-(constR&l,constR&r){if(l.y==r.y)returnR{l.x-r.x,l.y};returnR{l.x*r.y-l.y*r.x,l.y*r.y};}friendRoperator*(constR&l,constR&r){returnR{l.x*r.x,l.y*r.y};}friendRoperator/(constR&l,constR&r){returnR{l.x*r.y,l.y*r.x};}R&operator+=(constR&r){return(*this)=(*this)+r;}R&operator-=(constR&r){return(*this)=(*this)-r;}R&operator*=(constR&r){return(*this)=(*this)*r;}R&operator/=(constR&r){return(*this)=(*this)/r;}Roperator-()const{returnraw(-x,y);}Rinverse()const{assert(x!=0);Rr=raw(y,x);if(r.y<0)r.x=-r.x,r.y=-r.y;returnr;}Rpow(longlongp)const{Rres{1},base{*this};while(p){if(p&1)res*=base;base*=base;p>>=1;}returnres;}friendbooloperator==(constR&l,constR&r){returnl.x==r.x&&l.y==r.y;};friendbooloperator!=(constR&l,constR&r){returnl.x!=r.x||l.y!=r.y;};friendbooloperator<(constR&l,constR&r){returnU{l.x}*r.y<U{l.y}*r.x;};friendbooloperator<=(constR&l,constR&r){returnl<r||l==r;}friendbooloperator>(constR&l,constR&r){returnU{l.x}*r.y>U{l.y}*r.x;};friendbooloperator>=(constR&l,constR&r){returnl>r||l==r;}friendostream&operator<<(ostream&os,constR&r){os<<r.x;if(r.x!=0&&r.y!=1)os<<"/"<<r.y;returnos;}// T にキャストされるので T が bigint の場合は to_ll も要るTto_mint(Tmod)const{assert(mod!=0);Ta=y,b=mod,u=1,v=0,t;while(b>0){t=a/b;swap(a-=t*b,b);swap(u-=t*v,v);}returnU((u%mod+mod)%mod)*x%mod;}};usingRational=RationalBase<longlong,__int128_t>;usingFraction=Rational;