Jaydeep999997

Mercenaries

Oct 8th, 2020
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.53 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. const int N = 3e5 + 5;
  5. const int M = 25;
  6.  
  7. #define f(i,l,r) for(int i=l;i<=r;i++)
  8.  
  9. template<const int &MOD>
  10. struct _m_int  // This is our new type which will do operations under modulo MOD
  11. {
  12.     int val;   // Value of variable
  13.  
  14.     _m_int(int64_t v = 0)  // Typecasting into our data type from 64 bit integer
  15.     {
  16.         if (v < 0) v = v % MOD + MOD;
  17.         if (v >= MOD) v %= MOD;
  18.         val = v;
  19.     }
  20.  
  21.     static int mod_inv(int a, int m = MOD)
  22.     {
  23.         // https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Example
  24.         int g = m, r = a, x = 0, y = 1;
  25.  
  26.         while (r != 0)
  27.         {
  28.             int q = g / r;
  29.             g %= r; swap(g, r);
  30.             x -= q * y; swap(x, y);
  31.         }
  32.  
  33.         return x < 0 ? x + m : x;
  34.     }
  35.  
  36.     explicit operator int() const
  37.     {
  38.         return val;
  39.     }
  40.  
  41.     explicit operator int64_t() const
  42.     {
  43.         return val;
  44.     }
  45.  
  46.     _m_int& operator += (const _m_int &other)  // Addition
  47.     {
  48.         val -= MOD - other.val;
  49.         if (val < 0) val += MOD;
  50.         return *this;
  51.     }
  52.  
  53.     _m_int& operator -= (const _m_int &other)  // Subtraction
  54.     {
  55.         val -= other.val;
  56.         if (val < 0) val += MOD;
  57.         return *this;
  58.     }
  59.  
  60.     static unsigned fast_mod(uint64_t x, unsigned m = MOD) // Mod operation
  61.     {
  62. #if !defined(_WIN32) || defined(_WIN64)
  63.         return x % m;
  64. #endif
  65.         // Optimized mod for Codeforces 32-bit machines.
  66.         // x must be less than 2^32 * m for this to work, so that x / m fits in a 32-bit integer.
  67.         unsigned x_high = x >> 32, x_low = (unsigned) x;
  68.         unsigned quot, rem;
  69.         asm("divl %4\n"
  70.             : "=a" (quot), "=d" (rem)
  71.             : "d" (x_high), "a" (x_low), "r" (m));
  72.         return rem;
  73.     }
  74.  
  75.     _m_int& operator*=(const _m_int &other)  // Multiplication
  76.     {
  77.         val = fast_mod((uint64_t) val * other.val);
  78.         return *this;
  79.     }
  80.  
  81.     _m_int& operator/=(const _m_int &other)  // Division
  82.     {
  83.         return *this *= other.inv();
  84.     }
  85.  
  86.     friend _m_int operator+(const _m_int &a, const _m_int &b) { return _m_int(a) += b; }
  87.     friend _m_int operator-(const _m_int &a, const _m_int &b) { return _m_int(a) -= b; }
  88.     friend _m_int operator*(const _m_int &a, const _m_int &b) { return _m_int(a) *= b; }
  89.     friend _m_int operator/(const _m_int &a, const _m_int &b) { return _m_int(a) /= b; }
  90.  
  91.     _m_int& operator++()  // Pre-increment
  92.     {
  93.         val = val == MOD - 1 ? 0 : val + 1;
  94.         return *this;
  95.     }
  96.  
  97.     _m_int& operator--()  // Pre-decrement
  98.     {
  99.         val = val == 0 ? MOD - 1 : val - 1;
  100.         return *this;
  101.     }
  102.  
  103.     _m_int operator++(int) { _m_int before = *this; ++*this; return before; }  // Post increment
  104.     _m_int operator--(int) { _m_int before = *this; --*this; return before; }  // Post decrement
  105.  
  106.     _m_int operator-() const  // Change sign
  107.     {
  108.         return val == 0 ? 0 : MOD - val;
  109.     }
  110.  
  111.     // Boolean operators
  112.     bool operator==(const _m_int &other) const { return val == other.val; }
  113.     bool operator!=(const _m_int &other) const { return val != other.val; }
  114.     bool operator< (const _m_int &other) const { return val <  other.val; }
  115.     bool operator<=(const _m_int &other) const { return val <= other.val; }
  116.     bool operator> (const _m_int &other) const { return val >  other.val; }
  117.     bool operator>=(const _m_int &other) const { return val >= other.val; }
  118.  
  119.     _m_int inv() const  // Calculating inverse
  120.     {
  121.         return mod_inv(val);
  122.     }
  123.  
  124.     _m_int pow(int64_t p) const  // Calculating power
  125.     {
  126.         if (p < 0)
  127.             return inv().pow(-p);
  128.  
  129.         _m_int a = *this, result = 1;
  130.  
  131.         while (p > 0)
  132.         {
  133.             if (p & 1)
  134.             {
  135.                 result *= a;
  136.             }
  137.             a *= a;
  138.             p >>= 1;
  139.         }
  140.  
  141.         return result;
  142.     }
  143.  
  144.     friend ostream& operator<<(ostream &os, const _m_int &m)  // Writing output
  145.     {
  146.         return os << m.val;
  147.     }
  148.  
  149. };
  150.  
  151. extern const int MOD = 998244353;
  152. using mod_int = _m_int<MOD>;
  153.  
  154. mod_int fact[N], ifact[N];
  155. int L[N], R[N];
  156. int a[M], b[M];
  157. int cnt[N];
  158. int n, m;
  159. mod_int pref[M << 1][N];
  160.  
  161.  
  162. void pre()
  163. {
  164.     fact[0] = 1;
  165.     int i;
  166.     for (i = 1; i < N; i++)
  167.     {
  168.         fact[i] = (fact[i - 1] * i);
  169.     }
  170.     ifact[N - 1] = fact[N - 1].inv();
  171.     for (i = N - 2; i >= 0; i--)
  172.     {
  173.         ifact[i] = (ifact[i + 1] * (i + 1));
  174.     }
  175. }
  176.  
  177. mod_int ncr(int n, int r)
  178. {
  179.     if (r < 0 || n < 0 || n - r < 0)
  180.     {
  181.         return 0;
  182.     }
  183.     mod_int ans = (ifact[r] * ifact[n - r]);
  184.     ans = (ans * fact[n]);
  185.     return ans;
  186. }
  187.  
  188. mod_int incr(int n, int r)
  189. {
  190.     if (r < 0 || n < 0 || n - r < 0)
  191.     {
  192.         return 0;
  193.     }
  194.     mod_int ans = (fact[r] * ifact[n - r]);
  195.     ans = (ans * ifact[n]);
  196.     return ans;
  197. }
  198.  
  199. mod_int npr(int n, int r)
  200. {
  201.     if (r < 0 || n < 0 || n - r < 0)
  202.     {
  203.         return 0;
  204.     }
  205.     mod_int ans = ifact[n - r] * fact[n];
  206.     return ans;
  207. }
  208.  
  209. mod_int inpr(int n, int r)
  210. {
  211.     if (r < 0 || n < 0 || n - r < 0)
  212.     {
  213.         return 0;
  214.     }
  215.     mod_int ans = (fact[n - r] * ifact[n]);
  216.     return ans;
  217. }
  218.  
  219.  
  220. signed main()
  221. {
  222.     ios_base::sync_with_stdio(false);
  223.     cin.tie(nullptr); cout.tie(nullptr);
  224.  
  225.     pre();
  226.     cin >> n >> m;
  227.     f(i, 0, n - 1)
  228.     {
  229.         cin >> L[i] >> R[i];
  230.         cnt[L[i]]++;
  231.         cnt[R[i] + 1]--;
  232.     }
  233.     f(i, 1, n)
  234.     {
  235.         cnt[i] += cnt[i - 1];
  236.     }
  237.     f(i, 0, m - 1)
  238.     {
  239.         cin >> a[i] >> b[i];
  240.         a[i]--, b[i]--;
  241.     }
  242.     f(k, 0, m << 1)
  243.     {
  244.         f(s, 1, n)
  245.         {
  246.             pref[k][s] = (pref[k][s - 1] + ncr(cnt[s] - k, s - k));
  247.         }
  248.     }
  249.     mod_int ans = 0;
  250.     f(i, 0, (1 << m) - 1)
  251.     {
  252.         mod_int ways = 0;
  253.         int l = 1;
  254.         int r = n;
  255.         unordered_set<int> must;
  256.         bool even = true;
  257.         f(j, 0, m - 1)
  258.         {
  259.             if ((i >> j) & 1)
  260.             {
  261.                 even = !even;
  262.                 must.insert(a[j]);
  263.                 must.insert(b[j]);
  264.             }
  265.         }
  266.         for (auto &x : must)
  267.         {
  268.             l = max(l, L[x]);
  269.             r = min(r, R[x]);
  270.         }
  271.         if (l > r)
  272.         {
  273.             continue;
  274.         }
  275.         int k = must.size();
  276.         ways = pref[k][r] - pref[k][l - 1];
  277.         if (!even)
  278.         {
  279.             ans -= ways;
  280.         }
  281.         else
  282.         {
  283.             ans += ways;
  284.         }
  285.     }
  286.     cout << ans << endl;
  287.     return 0;
  288. }
Add Comment
Please, Sign In to add comment