結果
問題 | No.1354 Sambo's Treasure |
ユーザー | Chanyuh |
提出日時 | 2021-01-20 17:10:34 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 8,585 bytes |
コンパイル時間 | 1,646 ms |
コンパイル使用メモリ | 148,420 KB |
実行使用メモリ | 105,212 KB |
最終ジャッジ日時 | 2024-06-02 10:22:29 |
合計ジャッジ時間 | 7,645 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 33 ms
103,964 KB |
testcase_01 | AC | 33 ms
96,900 KB |
testcase_02 | AC | 33 ms
96,964 KB |
testcase_03 | AC | 34 ms
96,840 KB |
testcase_04 | AC | 33 ms
96,964 KB |
testcase_05 | AC | 33 ms
96,936 KB |
testcase_06 | AC | 33 ms
96,804 KB |
testcase_07 | AC | 34 ms
96,984 KB |
testcase_08 | AC | 33 ms
96,844 KB |
testcase_09 | AC | 33 ms
96,964 KB |
testcase_10 | AC | 32 ms
96,848 KB |
testcase_11 | AC | 33 ms
96,936 KB |
testcase_12 | AC | 34 ms
97,024 KB |
testcase_13 | AC | 34 ms
96,948 KB |
testcase_14 | AC | 33 ms
97,032 KB |
testcase_15 | AC | 34 ms
97,008 KB |
testcase_16 | AC | 33 ms
96,912 KB |
testcase_17 | AC | 33 ms
96,948 KB |
testcase_18 | AC | 33 ms
96,976 KB |
testcase_19 | AC | 32 ms
96,948 KB |
testcase_20 | AC | 33 ms
96,940 KB |
testcase_21 | AC | 33 ms
96,848 KB |
testcase_22 | AC | 33 ms
97,012 KB |
testcase_23 | TLE | - |
testcase_24 | -- | - |
testcase_25 | -- | - |
testcase_26 | -- | - |
testcase_27 | -- | - |
testcase_28 | -- | - |
testcase_29 | -- | - |
testcase_30 | -- | - |
testcase_31 | -- | - |
testcase_32 | -- | - |
testcase_33 | -- | - |
testcase_34 | -- | - |
testcase_35 | -- | - |
testcase_36 | -- | - |
testcase_37 | -- | - |
testcase_38 | -- | - |
testcase_39 | -- | - |
testcase_40 | -- | - |
testcase_41 | -- | - |
testcase_42 | -- | - |
testcase_43 | -- | - |
testcase_44 | -- | - |
testcase_45 | -- | - |
testcase_46 | -- | - |
testcase_47 | -- | - |
testcase_48 | -- | - |
testcase_49 | -- | - |
testcase_50 | -- | - |
testcase_51 | -- | - |
testcase_52 | -- | - |
testcase_53 | -- | - |
testcase_54 | -- | - |
testcase_55 | -- | - |
testcase_56 | -- | - |
testcase_57 | -- | - |
testcase_58 | -- | - |
testcase_59 | -- | - |
testcase_60 | -- | - |
testcase_61 | -- | - |
testcase_62 | -- | - |
testcase_63 | -- | - |
ソースコード
#include<iostream> #include<array> #include<string> #include<cstdio> #include<vector> #include<cmath> #include<algorithm> #include<functional> #include<iomanip> #include<queue> #include<ciso646> #include<random> #include<map> #include<set> #include<complex> #include<bitset> #include<stack> #include<unordered_map> #include<utility> #include<tuple> #include<cassert> using namespace std; typedef long long ll; typedef unsigned int ui; const ll mod = 998244353; const ll INF = (ll)1000000007 * 1000000007; typedef pair<int, int> P; #define stop char nyaa;cin>>nyaa; #define rep(i,n) for(int i=0;i<n;i++) #define per(i,n) for(int i=n-1;i>=0;i--) #define Rep(i,sta,n) for(int i=sta;i<n;i++) #define Per(i,sta,n) for(int i=n-1;i>=sta;i--) #define rep1(i,n) for(int i=1;i<=n;i++) #define per1(i,n) for(int i=n;i>=1;i--) #define Rep1(i,sta,n) for(int i=sta;i<=n;i++) typedef long double ld; const ld eps = 1e-8; const ld pi = acos(-1.0); typedef pair<ll, ll> LP; int dx[4]={1,-1,0,0}; int dy[4]={0,0,1,-1}; template<class T>bool chmax(T &a, const T &b) {if(a<b){a=b;return 1;}return 0;} template<class T>bool chmin(T &a, const T &b) {if(b<a){a=b;return 1;}return 0;} template<int mod> struct ModInt { long long x; static constexpr int MOD = mod; ModInt() : x(0) {} ModInt(long long y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {} explicit operator int() const {return x;} ModInt &operator+=(const ModInt &p) { if((x += p.x) >= mod) x -= mod; return *this; } ModInt &operator-=(const ModInt &p) { if((x += mod - p.x) >= mod) x -= mod; return *this; } ModInt &operator*=(const ModInt &p) { x = (int)(1LL * x * p.x % mod); return *this; } ModInt &operator/=(const ModInt &p) { *this *= p.inverse(); return *this; } ModInt operator-() const { return ModInt(-x); } ModInt operator+(const ModInt &p) const { return ModInt(*this) += p; } ModInt operator-(const ModInt &p) const { return ModInt(*this) -= p; } ModInt operator*(const ModInt &p) const { return ModInt(*this) *= p; } ModInt operator/(const ModInt &p) const { return ModInt(*this) /= p; } ModInt operator%(const ModInt &p) const { return ModInt(0); } bool operator==(const ModInt &p) const { return x == p.x; } bool operator!=(const ModInt &p) const { return x != p.x; } ModInt inverse() const{ int a = x, b = mod, u = 1, v = 0, t; while(b > 0) { t = a / b; a -= t * b; swap(a, b); u -= t * v; swap(u, v); } return ModInt(u); } ModInt power(long long n) const { ModInt ret(1), mul(x); while(n > 0) { if(n & 1) ret *= mul; mul *= mul; n >>= 1; } return ret; } ModInt power(const ModInt p) const{ return ((ModInt)x).power(p.x); } friend ostream &operator<<(ostream &os, const ModInt<mod> &p) { return os << p.x; } friend istream &operator>>(istream &is, ModInt<mod> &a) { long long x; is >> x; a = ModInt<mod>(x); return (is); } }; using modint = ModInt<mod>; struct ModFac{ public: vector<modint> f,i_f; int n; ModFac(int n_){ n=n_; f.resize(n+1,1); i_f.resize(n+1,1); for(int i=0;i<n;i++){ f[i+1]=f[i]*(modint)(i+1); } i_f[n]=f[n].power(mod-2); for(int i=n-1;i>=0;i--){ i_f[i]=i_f[i+1]*(modint)(i+1); } } ModFac(modint n_){ n=(int)n_; f.resize(n+1,1); i_f.resize(n+1,1); for(int i=0;i<n;i++){ f[i+1]=f[i]*(modint)(i+1); } i_f[n]=f[n].power(mod-2); for(int i=n-1;i>=0;i--){ i_f[i]=i_f[i+1]*(modint)(i+1); } } modint factorial(int x){ //cout << f.size() << endl; return f[x]; } modint inv_factorial(int x){ return i_f[x]; } modint comb(int m,int k){ if (m<0 or k<0) return 0; if (m<k) return 0; return f[m]*i_f[k]*i_f[m-k]; } }; template <typename Mint> struct NumberTheoreticTransformFriendlyModInt { vector<Mint> dw, idw; int max_base; Mint root; NumberTheoreticTransformFriendlyModInt() { const unsigned mod = Mint::MOD; assert(mod >= 3 && mod % 2 == 1); auto tmp = mod - 1; max_base = 0; while(tmp % 2 == 0) tmp >>= 1, max_base++; root = 2; while(root.power((mod - 1) >> 1) == 1) root += 1; assert(root.power(mod - 1) == 1); dw.resize(max_base); idw.resize(max_base); for(int i = 0; i < max_base; i++) { dw[i] = -root.power((mod - 1) >> (i + 2)); idw[i] = Mint(1) / dw[i]; } } void ntt(vector<Mint> &a) { const int n = (int)a.size(); assert((n & (n - 1)) == 0); assert(__builtin_ctz(n) <= max_base); for(int m = n; m >>= 1;) { Mint w = 1; for(int s = 0, k = 0; s < n; s += 2 * m) { for(int i = s, j = s + m; i < s + m; ++i, ++j) { auto x = a[i], y = a[j] * w; a[i] = x + y, a[j] = x - y; } w *= dw[__builtin_ctz(++k)]; } } } void intt(vector<Mint> &a, bool f = true) { const int n = (int)a.size(); assert((n & (n - 1)) == 0); assert(__builtin_ctz(n) <= max_base); for(int m = 1; m < n; m *= 2) { Mint w = 1; for(int s = 0, k = 0; s < n; s += 2 * m) { for(int i = s, j = s + m; i < s + m; ++i, ++j) { auto x = a[i], y = a[j]; a[i] = x + y, a[j] = (x - y) * w; } w *= idw[__builtin_ctz(++k)]; } } if(f) { Mint inv_sz = Mint(1) / n; for(int i = 0; i < n; i++) a[i] *= inv_sz; } } vector<Mint> multiply(vector<Mint> a, vector<Mint> b) { int need = a.size() + b.size() - 1; int nbase = 1; while((1 << nbase) < need) nbase++; int sz = 1 << nbase; a.resize(sz, 0); b.resize(sz, 0); ntt(a); ntt(b); Mint inv_sz = Mint(1) / sz; for(int i = 0; i < sz; i++) a[i] *= b[i] * inv_sz; intt(a, false); a.resize(need); return a; } }; int n,m,l,k; vector<P> cs,ts; modint dp1[100010][110]; ModFac MF(500010); vector<modint> calc(int s){ vector<P> vec={cs[s]}; bool f=false; rep(i,l){ if(cs[s].first<=ts[i].first && ts[i].first<=cs[s+1].first){ if(cs[s].second<=ts[i].second && ts[i].second<=cs[s+1].second){ if(cs[s+1]==ts[i]) f=true; if(cs[s]==ts[i] || cs[s+1]==ts[i]) continue; vec.push_back(ts[i]); } } } vec.push_back(cs[s+1]); int z=vec.size(); vector<vector<modint>> r(z,vector<modint>(z)); per(i,z){ Rep(j,i+1,z){ r[i][j]=MF.comb(vec[j].first-vec[i].first+vec[j].second-vec[i].second,vec[j].first-vec[i].first); Rep(k,i+1,j){ r[i][j]-=MF.comb(vec[k].first-vec[i].first+vec[k].second-vec[i].second,vec[k].first-vec[i].first)*r[k][j]; } } } vector<vector<modint>> dp2(z,vector<modint>(z+1)); //cout << z << " " << f << endl; dp2[0][0]=1; Rep(i,1,z){ rep(j,i){ rep(k,i+1){ dp2[i][k+1]+=r[j][i]*dp2[j][k]; } } // rep(k,i+2){ // cout << i << " " << k << " " << dp2[i][k] << endl; // } } vector<modint> res(z+1,0); Rep(k,1,z+1){ //cout << k << " " << dp2[z-1][k] << endl; if(f)res[k]=dp2[z-1][k]; else res[k-1]=dp2[z-1][k]; } return res; } void solve(){ NumberTheoreticTransformFriendlyModInt<modint> NTT; cin >> n >> m >> l >> k;chmin(k,l); cs.resize(m+2);ts.resize(l); cs[0]=P(0,0);cs[m+1]=P(n,n); rep(i,m){ cin >> cs[i+1].first >> cs[i+1].second; } rep(i,l){ cin >> ts[i].first >> ts[i].second; } sort(ts.begin(),ts.end()); vector<modint> dp(1,1); rep(i,m+1){ vector<modint> res=calc(i); // cout << res.size() << endl; // rep(j,res.size()){ // cout << res[j] << " "; // } // cout << "" << endl; dp=NTT.multiply(dp,res); } modint ans=0; rep(i,min((int)dp.size(),k)+1){ ans+=dp[i]; } cout << ans << endl; } int main(){ ios::sync_with_stdio(false); cin.tie(0); cout << fixed << setprecision(50); solve(); }