数论

扩展欧几里得算法(ExGCD) // ax+by=gcd(a,b)=g // check a>0 b>0 // if a != b, |x|<b, |y|<a template<typename T> void exgcd(T a,T b,T &g,T &x,T &y) { if(!b) { g=a; x=1; y=0; } else { exgcd(b,a%b,g,y,x); y-=a/b*x; } } 求逆元 template<typename T> void exgcd(T a,T b,T &g,T &x,T &y) { if(!b) { g=a; x=1; y=0; } else { exgcd(b,a%b,g,y,x); y-=a/b*x; } } template<typename T> T inv(T a,T m) { T g,x,y; exgcd(a,m,g,x,y); if(g!=1) return -1; // no inverse element if(x<0) x+=m; return x; } 不定方
模下计算 普通 const int MO=1e9+7; inline int add(int x,int y) { x+=y; if(x>=MO) x-=MO; return x; } inline int sub(int x,int y) { x-=y; if(x<0) x+=MO; return x; } inline int mul(int x,int y) { return 1LL*x*y%MO; } inline void addv(int &x,int y) { x+=y; if(x>=MO) x-=MO; } inline void subv(int &x,int y) { x-=y; if(x<0) x+=MO; } inline void mulv(int &x,int y) { x=1LL*x*y%MO; } int qp(int x,int n) { int ans=1; while(n) { if(n&1) { mulv(ans,x); } mulv(x,x); n>>=1; } return ans; } ModInt template<int MO=1000000007> struct ModInt { int x; ModInt(int x=0):x(x){ norm();