#include #include #include #include #include using namespace std; using mint=atcoder::modint998244353; class FPS : public std::vector { public: using std::vector::vector; FPS(const std::initializer_list l) : std::vector::vector(l) {} inline FPS& operator=(const std::vector &&f) & noexcept { std::vector::operator=(std::move(f)); return *this; } inline FPS& operator=(const std::vector &f) & { std::vector::operator=(f); return *this; } inline const mint operator[](int n) const noexcept { return n <= deg() ? unsafe_get(n) : 0; } inline mint& operator[](int n) noexcept { ensure_deg(n); return unsafe_get(n); } inline int size() const noexcept { return std::vector::size(); } inline int deg() const noexcept { return int(this->size()) - 1; } inline void cut(int max_deg) noexcept { if (deg() > max_deg) this->resize(std::max(0, max_deg + 1)); } inline int normalize() { while (this->size() and this->back() == 0) this->pop_back(); return deg(); } inline FPS pre(int max_deg) const noexcept { return FPS(this->begin(), this->begin() + std::min(this->deg(), std::max(0, max_deg)) + 1); } inline FPS operator+() const { return FPS(*this); } FPS operator-() const { FPS f(*this); for (auto &e : f) e = mint::mod() - e; return f; } FPS& operator+=(const FPS &g) { ensure_deg(g.deg()); for (int i = 0; i <= g.deg(); ++i) unsafe_get(i) += g.unsafe_get(i); return *this; } FPS& operator+=(FPS &&g) { ensure_deg(g.deg()); for (int i = 0; i <= g.deg(); ++i) unsafe_get(i) += g.unsafe_get(i); return *this; } FPS& operator-=(const FPS &g) { ensure_deg(g.deg()); for (int i = 0; i <= g.deg(); ++i) unsafe_get(i) -= g.unsafe_get(i); return *this; } FPS& operator-=(FPS &&g) { ensure_deg(g.deg()); for (int i = 0; i <= g.deg(); ++i) unsafe_get(i) -= g.unsafe_get(i); return *this; } inline FPS& operator*=(const FPS &g) { (*this) = atcoder::convolution(std::move(*this), g); return *this; } inline FPS& operator*=(FPS &&g) { (*this) = atcoder::convolution(std::move(*this), std::move(g)); return *this; } inline FPS& operator*=(const mint x) { for (auto &e : *this) e *= x; return *this; } inline FPS operator+(FPS &&g) const { return FPS(*this) += std::move(g); } inline FPS operator-(FPS &&g) const { return FPS(*this) -= std::move(g); } inline FPS operator*(FPS &&g) const { return FPS(*this) *= std::move(g); } inline FPS operator+(const FPS &g) const { return FPS(*this) += g; } inline FPS operator-(const FPS &g) const { return FPS(*this) -= g; } inline FPS operator*(const FPS &g) const { return FPS(*this) *= g; } inline FPS operator*(const mint x) const { return FPS(*this) *= x; } inline friend FPS operator*(const mint x, const FPS &f) { return f * x; } inline friend FPS operator*(const mint x, FPS &&f) { return f *= x; } FPS& inv_inplace(const int max_deg) { FPS res { unsafe_get(0).inv() }; for (int k = 1; k <= max_deg;) { k *= 2; int d = 0; for (const auto &e : this->pre(k) * (res * res)) { res[d] = res[d] + res[d] - e; if (++d > k) break; } } res.cut(max_deg); (*this) = std::move(res); return *this; } private: inline void ensure_deg(int d) { if (deg() < d) this->resize(d + 1, 0); } inline const mint& unsafe_get(int i) const { return std::vector::operator[](i); } inline mint& unsafe_get(int i) { return std::vector::operator[](i); } }; mint fac[5<<17],invfac[5<<17]; vector bernoulli(int n) { FPS a(n + 1); for (int i = 0; i <= n; ++i) a[i] = invfac[i+1]; a.inv_inplace(n); for (int i = 2; i <= n; ++i) a[i] *= fac[i]; return a; } mint comb(int a,int b){return fac[a]*invfac[b]*invfac[a-b];} mint lagrange_interpolation(const vector&y,long long x_) { int N=y.size(); if(N==0)return mint::raw(0); if(x_L(N),R(N); mint x=x_; L[0]=mint::raw(1); for(int i=1;i,pair >f(int H,int K) {//min(i,H-i+1,min(K,H-K+1)) pair,pair >ret; int T=min(K,H-K+1); ret.second.first=T; ret.second.second=0; {//i=1..(H+1)//2 int UP=(H+1)/2; if(TB; mint coef[5<<17]; mint S(int k,int n) {//Sum[i^k,{i,1,n}] mint ret=mint::raw(0); mint nn=mint::raw(1); for(int j=k;j>=0;j--) { nn*=mint::raw(n); ret+=comb(k+1,j)*B[j]*nn; } ret/=k+1; //cout<<"Sum[i^"<ff(int UP) { FPS f(N+1),g(N+1); mint t=mint::raw(1); for(int i=0;i<=N;i++) { t*=mint::raw(UP); f[i]=t*invfac[i+1]; g[i]=invfac[i+1]; } g.inv_inplace(N); f*=g; f=f.pre(N); vectorret(N+1); ret[0]=UP-1; for(int i=0;i&L,const vector&R) { mint ret=mint::raw(0); //vectorL=ff(h+1),R=ff(w+1); for(int n=0;n<=N;n++)ret+=coef[n]*L[n]*R[n]; return ret; } mint g2(pairh,pairw) { vectorF(N+5); F[0]=mint::raw(0); for(int i=1;i>H>>W>>N>>K; //B=bernoulli(N); //B[1]=-B[1]; invt=mint((long)(H-K+1)*(W-K+1)).inv(); { mint c=mint::raw(1); for(int i=0;i<=N;i++) { coef[i]=c*comb(N,i); c*=-invt; } } pair,pair >h=f(H,K),w=f(W,K); mint ans=(long)H*W; vectorL1=ff(h.first.first+1),L2=ff(h.first.second+1); vectorR1=ff(w.first.first+1),R2=ff(w.first.second+1); ans-=g1(L1,R1); ans-=g1(L1,R2); ans-=g1(L2,R1); ans-=g1(L2,R2); /* ans-=g1(h.first.first,w.first.first); ans-=g1(h.first.first,w.first.second); ans-=g1(h.first.second,w.first.first); ans-=g1(h.first.second,w.first.second); */ ans-=g2(h.first,w.second); ans-=g2(w.first,h.second); if(h.second.second>0&&w.second.second>0) { ans-=(1-mint((long)h.second.first*w.second.first)*invt).pow(N)*h.second.second*w.second.second; } cout<