Advertisement
isaf27

Global Round 7, solution of the problem G

Mar 19th, 2020
2,494
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.28 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. typedef long long ll;
  6. typedef pair<int, int> pi;
  7. #define prev _prev
  8. #define stack _stack
  9.  
  10. ll scal(pi a, pi b)
  11. {
  12.     return (ll)a.first * (ll)a.second + (ll)b.first * (ll)b.second;
  13. }
  14.  
  15. ll mul(pi a, pi b)
  16. {
  17.     return (ll)a.first * (ll)b.second - (ll)a.second * (ll)b.first;
  18. }
  19.  
  20. int half(pi a)
  21. {
  22.     if (a.second > 0 || (a.second == 0 && a.first >= 0))
  23.         return 0;
  24.     return 1;
  25. }
  26.  
  27. int half(pi a, pi b)
  28. {
  29.     ll pr = mul(a, b);
  30.     if (pr != 0)
  31.         return (pr <= 0);
  32.     return (scal(a, b) < 0);
  33. }
  34.  
  35. const int M = 210;
  36. const int MOD = 998244353;
  37.  
  38. int n, x[M], y[M], dp[M], val[M][M], ml[M], ei[M][M], first[M][M], last[M][M], sum[2 * M], ok[M][M];
  39. vector<int> v[M];
  40. vector<int> way[M][M];
  41.  
  42. pi vect(int i, int j)
  43. {
  44.     return make_pair(x[j] - x[i], y[j] - y[i]);
  45. }
  46.  
  47. pi vect(pi t)
  48. {
  49.     return make_pair(x[t.second] - x[t.first], y[t.second] - y[t.first]);
  50. }
  51.  
  52. void dfs_help(int p, int pr)
  53. {
  54.     int id = -1;
  55.     for (int i = 0; i < (int)v[p].size(); i++)
  56.     {
  57.         if (v[p][i] == pr)
  58.             id = i;
  59.         else
  60.             dfs_help(v[p][i], p);
  61.     }
  62.     if (id != -1)
  63.     {
  64.         swap(v[p][id], v[p].back());
  65.         v[p].pop_back();
  66.     }
  67. }
  68.  
  69. vector<int> stack;
  70.  
  71. void dfs_way(int p, int pr, int st)
  72. {
  73.     stack.push_back(p);
  74.     if (p != st && (int)stack.size() >= 3)
  75.     {
  76.         bool ch = true;
  77.         for (int i : stack)
  78.             if (mul(vect(st, p), vect(st, i)) < 0)
  79.             {
  80.                 ch = false;
  81.                 break;
  82.             }
  83.         if (ch)
  84.             way[st][p] = stack;
  85.     }
  86.     for (int i : v[p])
  87.         if (i != pr)
  88.             dfs_way(i, p, st);
  89.     stack.pop_back();
  90. }
  91.  
  92. bool cmp(pi a, pi b)
  93. {
  94.     pi va = vect(a);
  95.     pi vb = vect(b);
  96.     int ha = half(va);
  97.     int hb = half(vb);
  98.     if (ha != hb)
  99.         return ha < hb;
  100.     ll pr = mul(va, vb);
  101.     if (pr != 0)
  102.         return (pr > 0);
  103.     return a < b;
  104. }
  105.  
  106. bool good(pi a, pi b, pi c)
  107. {
  108.     int hb = half(a, b);
  109.     int hc = half(a, c);
  110.     if (hb != hc)
  111.         return hb < hc;
  112.     return mul(b, c) > 0;
  113. }
  114.  
  115. vector<int> g[M];
  116.  
  117. vector<int> dfs(int p)
  118. {
  119.     ml[p] = 1;
  120.     vector<int> now = {p};
  121.     for (int i : v[p])
  122.     {
  123.         vector<int> to = dfs(i);
  124.         for (int x : to)
  125.             now.push_back(x);
  126.         ml[p] = (ll)ml[p] * dp[i] % MOD;
  127.     }
  128.     dp[p] = ml[p];
  129.     for (int i : v[p])
  130.     {
  131.         int cur = ml[i];
  132.         for (int j : v[p])
  133.             if (j != i)
  134.                 cur = (ll)cur * dp[j] % MOD;
  135.         dp[p] += cur;
  136.         if (dp[p] >= MOD)
  137.             dp[p] -= MOD;
  138.     }
  139.     for (int i : now)
  140.         g[i].clear();
  141.     int k = 0;
  142.     for (int i : now)
  143.         for (int j : v[i])
  144.         {
  145.             g[i].push_back(j);
  146.             g[j].push_back(i);
  147.             ei[i][j] = k++;
  148.             ei[j][i] = k++;
  149.         }
  150.     for (int i : now)
  151.         for (int j : now)
  152.             ok[i][j] = 0;
  153.     vector<pi> al;
  154.     for (int i : now)
  155.         for (int j : now)
  156.             if (!way[i][j].empty() && mul(vect(i, j), vect(i, p)) >= 0)
  157.             {
  158.                 al.push_back(make_pair(i, j));
  159.                 first[i][j] = ei[way[i][j][0]][way[i][j][1]];
  160.                 last[i][j] = ei[way[i][j][(int)way[i][j].size() - 1]][way[i][j][(int)way[i][j].size() - 2]];
  161.                 if (val[i][j] != -1)
  162.                     continue;
  163.                 ok[i][j] = 1;
  164.                 val[i][j] = 1;
  165.                 for (int x = 0; x < (int)way[i][j].size(); x++)
  166.                 {
  167.                     int v_cur = way[i][j][x];
  168.                     pi lb, rb;
  169.                     if (x == 0)
  170.                     {
  171.                         lb = vect(v_cur, way[i][j][x + 1]);
  172.                         lb.first = -lb.first, lb.second = -lb.second;
  173.                     }
  174.                     else
  175.                         lb = vect(v_cur, way[i][j][x - 1]);
  176.                     if (x + 1 == (int)way[i][j].size())
  177.                     {
  178.                         rb = vect(v_cur, way[i][j][x - 1]);
  179.                         rb.first = -rb.first, rb.second = -rb.second;
  180.                     }
  181.                     else
  182.                         rb = vect(v_cur, way[i][j][x + 1]);
  183.                     for (int to : v[v_cur])
  184.                         if (good(lb, vect(v_cur, to), rb))
  185.                         {
  186.                             if (x != 0 && to == way[i][j][x - 1])
  187.                                 continue;
  188.                             if (x + 1 < (int)way[i][j].size() && to == way[i][j][x + 1])
  189.                                 continue;
  190.                             val[i][j] = (ll)val[i][j] * dp[to] % MOD;
  191.                         }
  192.                 }
  193.             }
  194.     sort(al.begin(), al.end(), cmp);
  195.     for (int v_st : now)
  196.         for (int ig : g[v_st])
  197.         {
  198.             if (half(vect(v_st, ig)))
  199.                 continue;
  200.             for (int ban = -1; ban <= 1; ban += 2)
  201.             {
  202.                 for (int i = 0; i < k; i++)
  203.                     sum[i] = 0;
  204.                 sum[ei[v_st][ig]] = 1;
  205.                 for (pi t : al)
  206.                 {
  207.                     if (ban == -1 && ok[t.first][t.second])
  208.                         continue;
  209.                     int S = first[t.first][t.second];
  210.                     int F = last[t.first][t.second];
  211.                     sum[F] += (ll)sum[S] * val[t.first][t.second] % MOD;
  212.                     if (sum[F] >= MOD)
  213.                         sum[F] -= MOD;
  214.                 }
  215.                 sum[ei[v_st][ig]]--;
  216.                 if (sum[ei[v_st][ig]] < 0)
  217.                     sum[ei[v_st][ig]] += MOD;
  218.                 dp[p] += ban * sum[ei[v_st][ig]];
  219.                 if (dp[p] >= MOD)
  220.                     dp[p] -= MOD;
  221.                 if (dp[p] < 0)
  222.                     dp[p] += MOD;
  223.             }
  224.         }
  225.     return now;
  226. }
  227.  
  228. int main()
  229. {
  230.     cin >> n;
  231.     for (int i = 0; i < n; i++)
  232.         cin >> x[i] >> y[i];
  233.     for (int i = 0; i < n - 1; i++)
  234.     {
  235.         int s, f;
  236.         cin >> s >> f;
  237.         s--, f--;
  238.         v[s].push_back(f);
  239.         v[f].push_back(s);
  240.     }
  241.     for (int i = 0; i < n; i++)
  242.         dfs_way(i, -1, i);
  243.     dfs_help(0, -1);
  244.     memset(val, -1, sizeof(val));
  245.     dfs(0);
  246.     cout << dp[0] << "\n";
  247.     return 0;
  248. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement