Advertisement
BaoJIaoPisu

Untitled

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