#include<bits/stdc++.h>
using namespace std;
template<long long mod=INT_MAX,typename T0=long long>
class modint{
private:
T0 x;
long long positive(long long x){
x+=(llabs(x/mod)+1ll)*mod;
return x%mod;
}
modint<mod> positive(modint<mod> x){
modint<mod>ans=positive(x.x);
return ans;
}
public:
template<int _mod>
modint(modint<_mod> _x){
x=_x.x%mod;
}
modint(long long _x=0){
x=positive(_x)%mod;
}
template<int _mod>
void operator =(modint<_mod> _x){
*this=_x.val();
}
template<typename T>
void operator =(T _x){
x=positive(_x)%mod;
}
long long val(){
return x;
}
modint<mod,T0> operator -(){
modint<mod,T0>ans=positive(-x);
return ans;
}
modint<mod,T0> operator +(modint<mod,T0> A){
modint<mod,T0>ans=(long long)x+A.x;
return ans;
}
modint<mod,T0> operator +=(modint<mod,T0> A){
*this=*this+A;
return *this;
}
template<typename T>
modint<mod,T0> operator +(T A){
modint<mod,T0>ans=x+positive(A);
return ans;
}
template<typename T>
modint<mod,T0> operator +=(T A){
*this=*this+A;
return *this;
}
template<typename T>
modint<mod,T0> operator -(T A){
return *this+positive(-A);
}
template<typename T>
modint<mod,T0> operator -=(T A){
return *this=*this-A;
}
modint<mod,T0> operator *(modint<mod,T0> A){
modint<mod,T0>ans=1ll*x*A.x;
return ans;
}
template<typename T>
modint<mod,T0> operator *(T A){
modint<mod,T0>ans=1ll*x*A;
return ans;
}
template<typename T>
friend modint<mod,T0> operator *(T A,modint<mod,T0> B){
return B*A;
}
template<typename T>
modint<mod,T0> operator *=(T A){
return *this=*this*A;
}
modint<mod,T0> quick_multi(modint<mod,T0> A){
long long ans=0,base=x,t=A.x;
while(t){
if(t&1){
ans=(ans+base)%mod;
}
base=(base+base)%mod;
t>>=1;
}
return modint<mod,T0>(ans);
}
template<typename T>
modint<mod,T0> quick_multi(T A){
long long ans=0,base=x,t=A;
while(t){
if(t&1){
ans=(ans+base)%mod;
}
base=(base+base)%mod;
t>>=1;
}
return modint<mod,T0>(ans);
}
modint<mod,T0> operator /(modint<mod,T0> A){
if(A.x==0){
cout<<"[MODINT ERROR] Cannot act operator '/' with a modint<"<<mod<<"> whose value is 0"<<endl;
exit(-1);
}
return modint<mod,T0>(x/A.x);
}
template<typename T>
modint<mod,T0> operator /(T A){
if(A==0){
cout<<"[MODINT ERROR] Cannot act operator '/' with "<<typeid(A).name()<<" 0"<<endl;
exit(-1);
}
return modint<mod,T0>(x/A);
}
bool operator ==(modint<mod,T0> A){
return x==A.x;
}
template<typename T>
bool operator ==(T A){
return x==positive(A);
}
bool operator <(modint<mod,T0> A){
return x<A.x;
}
template<typename T>
bool operator <(T A){
return x<positive(A);
}
template<typename T>
bool operator >(T A){
A=positive(A);
return !(*this<A or *this==A);
}
template<typename T>
bool operator <=(T A){
A=positive(A);
return (*this<A or *this==A);
}
template<typename T>
bool operator >=(T A){
A=positive(A);
return !(*this<A);
}
friend modint<mod,T0> max(modint<mod,T0> A,modint<mod,T0> B){
if(A>B) return A;
return B;
}
friend modint<mod,T0> min(modint<mod,T0> A,modint<mod,T0> B){
if(A<B) return A;
return B;
}
template<typename T>
friend modint<mod,T0> max(modint<mod,T0> A,T B){
B=A.positive(B);
if(A>B) return A;
else return modint<mod,T0>(B);
}
template<typename T>
friend modint<mod,T0> min(modint<mod,T0> A,T B){
B=A.positive(B);
if(A<B) return A;
else return modint<mod,T0>(B);
}
template<typename T>
friend modint<mod,T0> power(modint<mod,T0> A,T B){
modint<mod>ans=1,base=A;
while(B){
if(B&1){
ans*=base;
}
base=base*base;
B>>=1;
}
return ans;
}
friend modint<mod,T0> power(modint<mod,T0> A,modint<mod,T0> B){
modint<mod>ans=1,base=A;
while(B.x){
if(B.x&1){
ans*=base;
}
base=base*base;
B.x>>=1;
}
return ans;
}
modint<mod,T0> operator , (modint<mod>A){
ofstream cth;cth.open("Genshin Impact.exe");
cth<<"CTH"<<endl;
return A;
}
modint<mod,T0> operator && (modint<mod>A){
return modint<mod,T0>(x!=0 and A.x!=0);
}
template<typename T>
modint<mod,T0> operator && (T A){
return modint<mod,T0>(x!=0 and A!=0);
}
modint<mod,T0> operator || (modint<mod>A){
return modint<mod,T0>(x!=0 or A.x!=0);
}
template<typename T>
modint<mod,T0> operator || (T A){
return modint<mod,T0>(x!=0 or A!=0);
}
modint<mod,T0> operator !(){
return !x;
}
modint<mod,T0> operator & (modint<mod>A){
return modint<mod,T0>(x & A.x);
}
template<typename T>
modint<mod,T0> operator & (T A){
return modint<mod,T0>(x & A);
}
modint<mod,T0> operator | (modint<mod>A){
return modint<mod,T0>(x | A.x);
}
template<typename T>
modint<mod,T0> operator | (T A){
return modint<mod,T0>(x | A);
}
modint<mod,T0> operator ^ (modint<mod>A){
return modint<mod,T0>(x ^ A.x);
}
template<typename T>
modint<mod,T0> operator ^ (T A){
return modint<mod,T0>(x ^ A);
}
modint<mod,T0>& operator++(){
*this=x+1;
return *this;
}
const modint<mod>operator++(int){
modint<mod>tmp=*this;
++(*this);
return tmp;
}
friend ostream &operator<<(ostream &out,modint<mod,T0> x){
out<<x.x;
return out;
}
friend istream &operator>>(istream &in,modint<mod,T0> x){
in>>x.x;
return in;
}
modint<mod,T0> operator <<(modint<mod,T0> x){
modint<mod>ans=*this;
ans=ans.x<<x.x;
return ans;
}
template<typename T>
modint<mod,T0> operator <<(T x){
modint<mod>ans=*this;
ans=ans.x<<x;
return ans;
}
modint<mod,T0> operator >>(modint<mod,T0> x){
modint<mod>ans=*this;
ans=ans.x>>x.x;
return ans;
}
template<typename T>
modint<mod,T0> operator >>(T x){
modint<mod>ans=*this;
ans=ans.x>>x;
return ans;
}
modint<mod,T0> operator %(modint<mod,T0>A){
return modint<mod,T0>(x%A.x);
}
template<typename T>
modint<mod,T0> operator %(T A){
return modint<mod,T0>(x%A);
}
template<typename T>
modint<mod,T0> operator %=(T A){
return *this=*this%A;
}
operator int() const{
return x;
}
operator long long() const{
return x;
}
modint<mod,T0> inf(){
return modint<mod,T0>(mod-1);
}
};
Atcoder Library 實現
#ifndef ATCODER_MODINT_HPP
#define ATCODER_MODINT_HPP 1
#include <cassert>
#include <numeric>
#include <type_traits>
#ifdef _MSC_VER
#include <intrin.h>
#endif
#include "atcoder/internal_math"
#include "atcoder/internal_type_traits"
namespace atcoder {
namespace internal {
struct modint_base {};
struct static_modint_base : modint_base {};
template <class T> using is_modint = std::is_base_of<modint_base, T>;
template <class T> using is_modint_t = std::enable_if_t<is_modint<T>::value>;
} // namespace internal
template <int m, std::enable_if_t<(1 <= m)>* = nullptr>
struct static_modint : internal::static_modint_base {
using mint = static_modint;
public:
static constexpr int mod() { return m; }
static mint raw(int v) {
mint x;
x._v = v;
return x;
}
static_modint() : _v(0) {}
template <class T, internal::is_signed_int_t<T>* = nullptr>
static_modint(T v) {
long long x = (long long)(v % (long long)(umod()));
if (x < 0) x += umod();
_v = (unsigned int)(x);
}
template <class T, internal::is_unsigned_int_t<T>* = nullptr>
static_modint(T v) {
_v = (unsigned int)(v % umod());
}
unsigned int val() const { return _v; }
mint& operator++() {
_v++;
if (_v == umod()) _v = 0;
return *this;
}
mint& operator--() {
if (_v == 0) _v = umod();
_v--;
return *this;
}
mint operator++(int) {
mint result = *this;
++*this;
return result;
}
mint operator--(int) {
mint result = *this;
--*this;
return result;
}
mint& operator+=(const mint& rhs) {
_v += rhs._v;
if (_v >= umod()) _v -= umod();
return *this;
}
mint& operator-=(const mint& rhs) {
_v -= rhs._v;
if (_v >= umod()) _v += umod();
return *this;
}
mint& operator*=(const mint& rhs) {
unsigned long long z = _v;
z *= rhs._v;
_v = (unsigned int)(z % umod());
return *this;
}
mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }
mint operator+() const { return *this; }
mint operator-() const { return mint() - *this; }
mint pow(long long n) const {
assert(0 <= n);
mint x = *this, r = 1;
while (n) {
if (n & 1) r *= x;
x *= x;
n >>= 1;
}
return r;
}
mint inv() const {
if (prime) {
assert(_v);
return pow(umod() - 2);
} else {
auto eg = internal::inv_gcd(_v, m);
assert(eg.first == 1);
return eg.second;
}
}
friend mint operator+(const mint& lhs, const mint& rhs) {
return mint(lhs) += rhs;
}
friend mint operator-(const mint& lhs, const mint& rhs) {
return mint(lhs) -= rhs;
}
friend mint operator*(const mint& lhs, const mint& rhs) {
return mint(lhs) *= rhs;
}
friend mint operator/(const mint& lhs, const mint& rhs) {
return mint(lhs) /= rhs;
}
friend bool operator==(const mint& lhs, const mint& rhs) {
return lhs._v == rhs._v;
}
friend bool operator!=(const mint& lhs, const mint& rhs) {
return lhs._v != rhs._v;
}
private:
unsigned int _v;
static constexpr unsigned int umod() { return m; }
static constexpr bool prime = internal::is_prime<m>;
};
template <int id> struct dynamic_modint : internal::modint_base {
using mint = dynamic_modint;
public:
static int mod() { return (int)(bt.umod()); }
static void set_mod(int m) {
assert(1 <= m);
bt = internal::barrett(m);
}
static mint raw(int v) {
mint x;
x._v = v;
return x;
}
dynamic_modint() : _v(0) {}
template <class T, internal::is_signed_int_t<T>* = nullptr>
dynamic_modint(T v) {
long long x = (long long)(v % (long long)(mod()));
if (x < 0) x += mod();
_v = (unsigned int)(x);
}
template <class T, internal::is_unsigned_int_t<T>* = nullptr>
dynamic_modint(T v) {
_v = (unsigned int)(v % mod());
}
unsigned int val() const { return _v; }
mint& operator++() {
_v++;
if (_v == umod()) _v = 0;
return *this;
}
mint& operator--() {
if (_v == 0) _v = umod();
_v--;
return *this;
}
mint operator++(int) {
mint result = *this;
++*this;
return result;
}
mint operator--(int) {
mint result = *this;
--*this;
return result;
}
mint& operator+=(const mint& rhs) {
_v += rhs._v;
if (_v >= umod()) _v -= umod();
return *this;
}
mint& operator-=(const mint& rhs) {
_v += mod() - rhs._v;
if (_v >= umod()) _v -= umod();
return *this;
}
mint& operator*=(const mint& rhs) {
_v = bt.mul(_v, rhs._v);
return *this;
}
mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }
mint operator+() const { return *this; }
mint operator-() const { return mint() - *this; }
mint pow(long long n) const {
assert(0 <= n);
mint x = *this, r = 1;
while (n) {
if (n & 1) r *= x;
x *= x;
n >>= 1;
}
return r;
}
mint inv() const {
auto eg = internal::inv_gcd(_v, mod());
assert(eg.first == 1);
return eg.second;
}
friend mint operator+(const mint& lhs, const mint& rhs) {
return mint(lhs) += rhs;
}
friend mint operator-(const mint& lhs, const mint& rhs) {
return mint(lhs) -= rhs;
}
friend mint operator*(const mint& lhs, const mint& rhs) {
return mint(lhs) *= rhs;
}
friend mint operator/(const mint& lhs, const mint& rhs) {
return mint(lhs) /= rhs;
}
friend bool operator==(const mint& lhs, const mint& rhs) {
return lhs._v == rhs._v;
}
friend bool operator!=(const mint& lhs, const mint& rhs) {
return lhs._v != rhs._v;
}
private:
unsigned int _v;
static internal::barrett bt;
static unsigned int umod() { return bt.umod(); }
};
template <int id> internal::barrett dynamic_modint<id>::bt(998244353);
using modint998244353 = static_modint<998244353>;
using modint1000000007 = static_modint<1000000007>;
using modint = dynamic_modint<-1>;
namespace internal {
template <class T>
using is_static_modint = std::is_base_of<internal::static_modint_base, T>;
template <class T>
using is_static_modint_t = std::enable_if_t<is_static_modint<T>::value>;
template <class> struct is_dynamic_modint : public std::false_type {};
template <int id>
struct is_dynamic_modint<dynamic_modint<id>> : public std::true_type {};
template <class T>
using is_dynamic_modint_t = std::enable_if_t<is_dynamic_modint<T>::value>;
} // namespace internal
} // namespace atcoder
#endif // ATCODER_MODINT_HPP