You are on page 1of 6

#include<bits/stdc++.

h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
// #include <sys/resource.h>
using namespace std;
using namespace __gnu_pbds;

template <typename T>


using ordered_set = tree<T, null_type, less<T>, rb_tree_tag,
tree_order_statistics_node_update>;

template <typename T>


using ordered_multiset = tree<T, null_type, less_equal<T>, rb_tree_tag,
tree_order_statistics_node_update>;

// DEFINE STATEMENTS
const long long INF = 1e18;
const int INFINT = INT_MAX/2;
#define num1 1000000007
#define num2 998244353
#define REP(i,a,n) for(ll i=a;i<n;i++)
#define REPd(i,a,n) for(ll i=a; i>=n; i--)
#define pb push_back
#define f first
#define s second
#define fix(f,n) std::fixed<<std::setprecision(n)<<f
#define all(x) x.begin(), x.end()
#define M_PI 3.14159265358979323846
#define epsilon (double)(0.000000001)
#define popcount __builtin_popcountll
#define fileio(x, y) freopen(x, "r", stdin); freopen(y, "w", stdout);
#define out(x) cout << ((x) ? "YES\n" : "NO\n")
#define CASE(x, y) cout << "Case #" << x << ":" << " \n"[y]
#define start_clock() auto start_time = std::chrono::high_resolution_clock::now();
auto end_time = start_time;
#define measure() end_time = std::chrono::high_resolution_clock::now(); cerr <<
(end_time - start_time)/std::chrono::milliseconds(1) << "ms" << endl;
#define reset_clock() start_time = std::chrono::high_resolution_clock::now();

typedef long long ll;


typedef long double ld;
typedef vector<long long> vll;
typedef pair<long long, long long> pll;
typedef vector<pair<long long, long long>> vpll;
typedef vector<int> vii;

// DEBUG FUNCTIONS
#ifdef LOCALY

template<typename T>
void __p(T a) {
cout<<a;
}
template<typename T, typename F>
void __p(pair<T, F> a) {
cout<<"{";
__p(a.first);
cout<<",";
__p(a.second);
cout<<"}";
}
template<typename T>
void __p(std::vector<T> a) {
cout<<"{";
for(auto it=a.begin(); it<a.end(); it++)
__p(*it),cout<<",}"[it+1==a.end()];
}
template<typename T>
void __p(std::set<T> a) {
cout<<"{";
for(auto it=a.begin(); it!=a.end();){
__p(*it);
cout<<",}"[++it==a.end()];
}

}
template<typename T>
void __p(std::multiset<T> a) {
cout<<"{";
for(auto it=a.begin(); it!=a.end();){
__p(*it);
cout<<",}"[++it==a.end()];
}
}
template<typename T, typename F>
void __p(std::map<T,F> a) {
cout<<"{\n";
for(auto it=a.begin(); it!=a.end();++it)
{
__p(it->first);
cout << ": ";
__p(it->second);
cout<<"\n";
}
cout << "}\n";
}

template<typename T, typename ...Arg>


void __p(T a1, Arg ...a) {
__p(a1);
__p(a...);
}
template<typename Arg1>
void __f(const char *name, Arg1 &&arg1) {
cout<<name<<" : ";
__p(arg1);
cout<<endl;
}
template<typename Arg1, typename ... Args>
void __f(const char *names, Arg1 &&arg1, Args &&... args) {
int bracket=0,i=0;
for(;; i++)
if(names[i]==','&&bracket==0)
break;
else if(names[i]=='(')
bracket++;
else if(names[i]==')')
bracket--;
const char *comma=names+i;
cout.write(names,comma-names)<<" : ";
__p(arg1);
cout<<" | ";
__f(comma+1,args...);
}
#define trace(...) cout<<"Line:"<<__LINE__<<" ", __f(#__VA_ARGS__, __VA_ARGS__)
#else
#define trace(...)
#define error(...)
#endif

// DEBUG FUNCTIONS END

// CUSTOM HASH TO SPEED UP UNORDERED MAP AND TO AVOID FORCED CLASHES


struct custom_hash {
static uint64_t splitmix64(uint64_t x) {
x += 0x9e3779b97f4a7c15;
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
return x ^ (x >> 31);
}

size_t operator()(uint64_t x) const {


static const uint64_t FIXED_RANDOM =
chrono::steady_clock::now().time_since_epoch().count();
return splitmix64(x + FIXED_RANDOM);
}
};

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); // FOR


RANDOM NUMBER GENERATION

ll mod_exp(ll a, ll b, ll c)
{
ll res=1; a=a%c;
while(b>0)
{
if(b%2==1)
res=(res*a)%c;
b/=2;
a=(a*a)%c;
}
return res;
}
ll norm(ll a,ll b)
{
return (((a = a%b) < 0) ? a + b : a);
}
ll gcdExtended(ll,ll,ll *,ll *);
ll modInverse(ll a, ll m)
{
ll x, y;
ll g = gcdExtended(a, m, &x, &y);
g++; g--; //this line was added just to remove compiler warning
ll res = (x%m + m) % m;
return res;
}
ll gcdExtended(ll a, ll b, ll *x, ll *y)
{
if (a == 0)
{
*x = 0, *y = 1;
return b;
}
ll x1, y1;
ll gcd = gcdExtended(b%a, a, &x1, &y1);
*x = y1 - (b/a) * x1;
*y = x1;
return gcd;
}

struct Graph
{
vector<vector<int>> adj;
Graph(int n): adj(n+1) {}
void add_edge(int a, int b, bool directed = false)
{
adj[a].pb(b);
if(!directed) adj[b].pb(a);
}
};

//Dont forget to reset MOD if some other MOD is needed


const ll MOD = 998244353;

//Comment the line above and uncomment the line below if problem requires more than
1 MOD
//After uncommenting the below line, declaration of Mint becomes [ Mint<mod> M; ]

//template<ll MOD>
class Mint
{
//WARNING:
//Be very careful not to use two Mints with different mods for any operation
//No guarantee of behavior in this case
public:
ll val;
static ll mod_exp(ll a, ll b){ ll res=1; a=a%MOD; while(b>0){ if(b%2==1)
res=(res*a)%MOD; b/=2; a=(a*a)%MOD; } return res; }
static ll gcdExtended(ll a, ll b, ll *x, ll *y) { if (a == 0) { *x = 0, *y =
1; return b; } ll x1, y1; ll gcd = gcdExtended(b%a, a, &x1, &y1);*x = y1 - (b/a) *
x1; *y = x1; return gcd; }
static ll modInverse(ll a) { ll x, y; ll g = gcdExtended(a, MOD, &x, &y);
g++; ll res = (x%MOD); if(res < 0) res += MOD; return res;}
Mint(){ val = 0;}
Mint(ll x){ val = x%MOD; if(val < 0) val += MOD;}
Mint& operator +=(const Mint &other){ val += other.val; if(val >= MOD) val
-= MOD; return (*this); }
Mint& operator -=(const Mint &other){ val -= other.val;if(val < 0) val +=
MOD; return (*this); }
Mint& operator *=(const Mint &other){ val = (val * other.val)%MOD; return
(*this); }
Mint& operator /=(const Mint &other){ val = (val * modInverse(other.val))
% MOD; return (*this); }
Mint& operator =(const Mint &other) { val = other.val; return (*this); }
Mint operator +(const Mint &other) const { return Mint(*this) +=
other; }
Mint operator -(const Mint &other) const { return Mint(*this) -=
other; }
Mint operator *(const Mint &other) const { return Mint(*this) *=
other; }
Mint operator /(const Mint &other) const { return Mint(*this) /=
other; }
bool operator ==(const Mint &other) const { return val == other.val; }

Mint operator ++() { ++val; if(val == MOD) val = 0; return (*this); }


Mint operator ++(int) { val++; if(val == MOD) val = 0; return Mint(val-1); }
Mint operator --() { --val; if(val == -1) val = MOD-1; return (*this); }
Mint operator --(int) { val--; if(val == -1) val = MOD-1; return Mint(val+1);
}

// ^ has very low precedence, careful!!

template<typename T>
Mint& operator ^=(const T &other){ val = mod_exp(val, other); return
(*this); }
template<typename T>
Mint operator ^(const T &other) const { return Mint(*this) ^= other; }

Mint& operator ^=(const Mint &other){ val = mod_exp(val, other.val); return


(*this); }
Mint operator ^(const Mint &other) const { return Mint(*this) ^= other; }

template<typename T>
explicit operator T() { return (T)val; }
template<typename T>
friend Mint operator +(T other, const Mint &M){ return Mint(other) + M; }
template<typename T>
friend Mint operator -(T other, const Mint &M){ return Mint(other) - M; }
template<typename T>
friend Mint operator *(T other, const Mint &M){ return Mint(other) * M; }
template<typename T>
friend Mint operator /(T other, const Mint &M){ return Mint(other) / M; }
template<typename T>
friend Mint operator ^(T other, const Mint &M){ return Mint(other) ^ M; }

friend std::ostream &operator << (std::ostream &output, const Mint &M)


{ return output << M.val; }
friend std::istream &operator >> (std::istream &input, Mint &M) { input >>
M.val; M.val %= MOD; return input;}
};

const int MAXN = 1e6+5;


Mint facto[MAXN], invfacto[MAXN];

void pre()
{
facto[0] = 1;
for(int i=1; i<MAXN; i++) facto[i] = i*facto[i-1];
invfacto[MAXN-1] = 1/facto[MAXN-1];
for(int i=MAXN-2; i>=0; i--) invfacto[i] = (i+1)*invfacto[i+1];
}

Mint nCr(ll a, ll b)
{
if(b < 0 || b > a) return Mint(0);
return (facto[a]*invfacto[b]*invfacto[a-b]);
}

You might also like