[namespace hdk] modint

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>
		modint<_mod,T0> operator =(modint<_mod,T0> _x){
			*this=_x.val();
			return _x;
		}
		template<typename T>
		T operator =(T _x){
			x=positive(_x)%mod;
			return _x;
		}
		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);
		}
		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,T0>operator++(int){
			modint<mod,T0>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 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


posted @ 2024-09-13 17:49  HaneDaniko  阅读(28)  评论(3编辑  收藏  举报