Advertisement
BaoJIaoPisu

Untitled

Nov 18th, 2022
529
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.73 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. using ll = long long;
  6. using ld = long double;
  7. using ull = unsigned long long;
  8.  
  9. using pii = pair<int, int>;
  10. using pll = pair<ll, ll>;
  11. using pld = pair<ld, ld>;
  12.  
  13. #define fi first
  14. #define se second
  15. #define left BAO
  16. #define right ANH
  17. #define pb push_back
  18. #define pf push_front
  19. #define mp make_pair
  20. #define ins insert
  21. #define btpc __builtin_popcount
  22. #define btclz __builtin_clz
  23.  
  24. #define sz(x) (int)(x.size());
  25. #define all(x) x.begin(), x.end()
  26. #define debug(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
  27.  
  28. mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  29.  
  30. int d4x[4] = {1, 0, -1, 0}; int d4y[4] = {0, 1, 0, -1};
  31. int d8x[8] = {0, 1, 1, 1, 0, -1, -1, -1};
  32. int d8y[8] = {1, 1, 0, -1, -1, -1, 0, 1};
  33.  
  34. template<class X, class Y>
  35.     bool minimize(X &x, const Y &y) {
  36.         if (x > y)
  37.         {
  38.             x = y;
  39.             return true;
  40.         }
  41.         return false;
  42.     }
  43. template<class X, class Y>
  44.     bool maximize(X &x, const Y &y) {
  45.         if (x < y)
  46.         {
  47.             x = y;
  48.             return true;
  49.         }
  50.         return false;
  51.     }
  52.  
  53. const int MOD = 998244353; //998244353
  54.  
  55. template<class X, class Y>
  56.     void add(X &x, const Y &y) {
  57.         x = (x + y);
  58.         if(x >= MOD) x -= MOD;
  59.     }
  60.  
  61. template<class X, class Y>
  62.     void sub(X &x, const Y &y) {
  63.         x = (x - y);
  64.         if(x < 0) x += MOD;
  65.     }
  66.  
  67. /* Author : Le Ngoc Bao Anh, 12A5, LQD High School for Gifted Student*/
  68.  
  69. const ll INF = 1e9;
  70. const int N = 105;
  71.  
  72. template <typename T> T mod_inv_in_range(T a, T m) {
  73.     // assert(0 <= a && a < m);
  74.     T x = a, y = m;
  75.     T vx = 1, vy = 0;
  76.     while (x) {
  77.         T k = y / x;
  78.         y %= x;
  79.         vy -= k * vx;
  80.         std::swap(x, y);
  81.         std::swap(vx, vy);
  82.     }
  83.     assert(y == 1);
  84.     return vy < 0 ? m + vy : vy;
  85. }
  86.  
  87. template <typename T> T mod_inv(T a, T m) {
  88.     a %= m;
  89.     a = a < 0 ? a + m : a;
  90.     return mod_inv_in_range(a, m);
  91. }
  92.  
  93. template <int MOD_> struct modnum {
  94.     static constexpr int MOD = MOD_;
  95.     static_assert(MOD_ > 0, "MOD must be positive");
  96.  
  97.     using ll = long long;
  98.  
  99.     int v;
  100.  
  101. public:
  102.  
  103.     modnum() : v(0) {}
  104.     modnum(ll v_) : v(int(v_ % MOD)) { if (v < 0) v += MOD; }
  105.     explicit operator int() const { return v; }
  106.     friend std::ostream& operator << (std::ostream& out, const modnum& n) { return out << int(n); }
  107.     friend std::istream& operator >> (std::istream& in, modnum& n) { ll v_; in >> v_; n = modnum(v_); return in; }
  108.  
  109.     friend bool operator == (const modnum& a, const modnum& b) { return a.v == b.v; }
  110.     friend bool operator != (const modnum& a, const modnum& b) { return a.v != b.v; }
  111.  
  112.     modnum inv() const {
  113.         modnum res;
  114.         res.v = mod_inv_in_range(v, MOD);
  115.         return res;
  116.     }
  117.     friend modnum inv(const modnum& m) { return m.inv(); }
  118.     modnum neg() const {
  119.         modnum res;
  120.         res.v = v ? MOD-v : 0;
  121.         return res;
  122.     }
  123.     friend modnum neg(const modnum& m) { return m.neg(); }
  124.  
  125.     modnum operator- () const {
  126.         return neg();
  127.     }
  128.     modnum operator+ () const {
  129.         return modnum(*this);
  130.     }
  131.  
  132.     modnum& operator ++ () {
  133.         v ++;
  134.         if (v == MOD) v = 0;
  135.         return *this;
  136.     }
  137.     modnum& operator -- () {
  138.         if (v == 0) v = MOD;
  139.         v --;
  140.         return *this;
  141.     }
  142.     modnum& operator += (const modnum& o) {
  143.         v -= MOD-o.v;
  144.         v = (v < 0) ? v + MOD : v;
  145.         return *this;
  146.     }
  147.     modnum& operator -= (const modnum& o) {
  148.         v -= o.v;
  149.         v = (v < 0) ? v + MOD : v;
  150.         return *this;
  151.     }
  152.     modnum& operator *= (const modnum& o) {
  153.         v = int(ll(v) * ll(o.v) % MOD);
  154.         return *this;
  155.     }
  156.     modnum& operator /= (const modnum& o) {
  157.         return *this *= o.inv();
  158.     }
  159.  
  160.     friend modnum operator ++ (modnum& a, int) { modnum r = a; ++a; return r; }
  161.     friend modnum operator -- (modnum& a, int) { modnum r = a; --a; return r; }
  162.     friend modnum operator + (const modnum& a, const modnum& b) { return modnum(a) += b; }
  163.     friend modnum operator - (const modnum& a, const modnum& b) { return modnum(a) -= b; }
  164.     friend modnum operator * (const modnum& a, const modnum& b) { return modnum(a) *= b; }
  165.     friend modnum operator / (const modnum& a, const modnum& b) { return modnum(a) /= b; }
  166. };
  167. using num = modnum<MOD>;
  168.  
  169. num f[N], invf[N];
  170. int w[N], v[N];
  171. num dp[N][N][N], combi[N][N];
  172.  
  173. num power(num a, ll b) {
  174.     if(b == 0) return 1;
  175.     num ans = power(a, b / 2);
  176.     ans = ans * ans;
  177.     if(b & 1) ans = ans * a;
  178.     return ans;
  179. }
  180.  
  181.  
  182. void BaoJiaoPisu() {
  183.     int n, we, k; cin >> n >> we >> k;
  184.     for(int i = 1; i <= n; i++) cin >> w[i] >> v[i];
  185.  
  186.     f[0] = 1;
  187.     for(int i = 1; i <= k; i++) f[i] = f[i - 1] * i;
  188.     invf[k] = 1 / f[k];
  189.     for(int i = k - 1; i >= 0; i--) invf[i] = invf[i + 1] * (i + 1);
  190.  
  191.     auto C = [&](int n, int k) -> num {
  192.         //n is very high, but k is small (<= 100);
  193.         if(n < k || k < 0) return 0;
  194.  
  195.         num ans = 1;
  196.         for(int i = n; i > n - k; i--) ans *= i;
  197.         ans *= invf[k];
  198.         return ans;
  199.     };
  200.  
  201.     auto S = [&](int n, int k) -> num {
  202.         //Stirling number of the second kind
  203.         if(n < k || k < 0) return 0;
  204.         num ans = 0;
  205.         for(int i = 0; i <= k; i++) {
  206.             if(i & 1) ans -= C(k, i) * power(k - i, n);
  207.             else ans += C(k, i) * power(k - i, n);
  208.         }
  209.  
  210.         ans /= f[k];
  211.         return ans;
  212.     };
  213.  
  214.      //n ^ k = sigma(i : 0 -> k) S(k, i) * C(n, i) * i!
  215.  
  216.     dp[0][0][0] = 1;
  217.     //precalculate combi
  218.  
  219.     for(int i = 1; i <= n; i++) {
  220.         for(int j = 0; j <= k; j++) {
  221.             combi[i][j] = C(v[i], j);
  222.         }
  223.     }
  224.  
  225.     //dp[index][weight][combi]
  226.  
  227.     for(int i = 0; i < n; i++) {
  228.         for(int j = 0; j <= we; j++) {
  229.             for(int x = 0; x <= k; x++) {
  230.                 dp[i + 1][j][x] += dp[i][j][x];
  231.                 if(j + w[i + 1] <= we) {
  232.                     for(int y = 0; y <= k - x; y++) {
  233.                         dp[i + 1][j + w[i + 1]][x + y] += dp[i][j][x] * combi[i + 1][y];
  234.                     }
  235.                 }
  236.             }
  237.         }
  238.     }
  239.  
  240.     num ans = 0;
  241.     for(int i = 0; i <= k; i++) {
  242.         num Stirling = S(k, i);
  243.         for(int j = 0; j <= we; j++) {
  244.             ans += Stirling * f[i] * dp[n][j][i];
  245.         }
  246.     }
  247.  
  248.     cout << ans;
  249. }
  250.  
  251. int main()
  252. {
  253.     ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  254.     #ifndef ONLINE_JUDGE
  255.     freopen("input.txt", "r", stdin);
  256.     freopen("output.txt", "w", stdout);
  257.     #else
  258.     //online
  259.     #endif
  260.  
  261.     int tc = 1, ddd = 0;
  262.     // cin >> tc;
  263.     while(tc--) {
  264.         //ddd++;
  265.         //cout << "Case #" << ddd << ": ";
  266.         BaoJiaoPisu();
  267.     }
  268. }
  269.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement