Advertisement
vlatkovski

JOI Open 2020 building4

Mar 20th, 2020
328
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.44 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. typedef pair<int, int> pii;
  5.  
  6. const int N = 500500;
  7.  
  8. int n;
  9. int a[2][2*N];
  10. bool reach_left[2][2*N];
  11. bool reach_right[2][2*N];
  12. int mn[2][2*N][2];
  13. int mx[2][2*N][2];
  14.  
  15. int main() {
  16.     ios::sync_with_stdio(false);
  17.     cin.tie(0);
  18.     cin >> n;
  19.     for (int j = 0; j < 2; ++j) {
  20.         for (int i = 1; i <= 2*n; ++i) {
  21.             cin >> a[j][i];
  22.             reach_left[j][i] = false;
  23.             reach_right[j][i] = false;
  24.         }
  25.     }
  26.     reach_left[0][1] = true;
  27.     reach_left[1][1] = true;
  28.     for (int i = 1; i < 2*n; ++i) {
  29.         for (int j = 0; j < 2; ++j) {
  30.             if (!reach_left[j][i]) continue;
  31.             for (int k = 0; k < 2; ++k) {
  32.                 if (a[j][i] <= a[k][i+1]) {
  33.                     reach_left[k][i+1] = true;
  34.                 }
  35.             }
  36.         }
  37.     }
  38.     reach_right[0][2*n] = true;
  39.     reach_right[1][2*n] = true;
  40.     for (int i = 2*n-1; i >= 1; --i) {
  41.         for (int j = 0; j < 2; ++j) {
  42.             for (int k = 0; k < 2; ++k) {
  43.                 if (!reach_right[k][i+1]) continue;
  44.                 if (a[j][i] <= a[k][i+1]) {
  45.                     reach_right[j][i] = true;
  46.                 }
  47.             }
  48.         }
  49.     }
  50.     for (int j = 0; j < 2; ++j) {
  51.         if (!reach_left[j][2*n] || !reach_right[j][2*n]) {
  52.             for (int c = 0; c < 2; ++c) {
  53.                 mn[j][2*n][c] = 2*N;
  54.                 mx[j][2*n][c] = -1;
  55.             }
  56.         } else {
  57.             for (int c = 0; c < 2; ++c) {
  58.                 mn[j][2*n][c] = (j == c);
  59.                 mx[j][2*n][c] = (j == c);
  60.             }
  61.         }
  62.     }
  63.     for (int i = 2*n-1; i >= 1; --i) {
  64.         int cnt_bad = 0;
  65.         for (int j = 0; j < 2; ++j) {
  66.             for (int c = 0; c < 2; ++c) {
  67.                 mn[j][i][c] = 2*N;
  68.                 mx[j][i][c] = -1;
  69.             }
  70.             if (!reach_left[j][i] || !reach_right[j][i]) continue;
  71.             for (int k = 0; k < 2; ++k) {
  72.                 if (!reach_left[k][i+1] || !reach_right[k][i+1]) continue;
  73.                 if (a[j][i] > a[k][i+1]) continue;
  74.                 for (int c = 0; c < 2; ++c) {
  75.                     mn[j][i][c] = min(mn[j][i][c], (j == c) + mn[k][i+1][c]);
  76.                     mx[j][i][c] = max(mx[j][i][c], (j == c) + mx[k][i+1][c]);
  77.                 }
  78.             }
  79.             if (mn[j][i][0] == 2*N) {
  80.                 ++cnt_bad;
  81.             }
  82.         }
  83.         if (cnt_bad == 2) {
  84.             cout << -1 << '\n';
  85.             return 0;
  86.         }
  87.     }
  88.     /*
  89.     cout << "reach_left:\n";
  90.     for (int j = 0; j < 2; ++j) {
  91.         for (int i = 1; i <= 2*n; ++i) {
  92.             cout << reach_left[j][i] << ' ';
  93.         }
  94.         cout << "\n";
  95.     }
  96.     cout << "reach_right:\n";
  97.     for (int j = 0; j < 2; ++j) {
  98.         for (int i = 1; i <= 2*n; ++i) {
  99.             cout << reach_right[j][i] << ' ';
  100.         }
  101.         cout << "\n";
  102.     }
  103.     cout << "counts:\n";
  104.     for (int j = 0; j < 2; ++j) {
  105.         for (int i = 1; i <= 2*n; ++i) {
  106.             if (mn[j][i][0]==2*N)cout<<"(x-x,x-x) ";
  107.             else {
  108.                 cout<<"("<<mn[j][i][0]<<"-"<<mx[j][i][0]<<",";
  109.                 cout<<mn[j][i][1]<<"-"<<mx[j][i][1]<<") ";
  110.             }
  111.         }
  112.         cout << "\n";
  113.     }
  114.     */
  115.     int rem[2] = {n, n};
  116.     int prev_j = -1;
  117.     for (int i = 1; i <= 2*n; ++i) {
  118.         bool found = false;
  119.         for (int j = 0; j < 2; ++j) {
  120.             if (!reach_left[j][i] || !reach_right[j][i]) continue;
  121.             if (i > 1 && a[prev_j][i-1] > a[j][i]) continue;
  122.             // if arriving at (j, i)
  123.             bool good = true;
  124.             for (int c = 0; c < 2; ++c) {
  125.                 if (mn[j][i][c] <= rem[c] && rem[c] <= mx[j][i][c]) {
  126.                    
  127.                 } else {
  128.                     good = false;
  129.                     break;
  130.                 }
  131.             }
  132.             if (good) {
  133.                 // can arrive at (j, i);
  134.                 --rem[j];
  135.                 //cout << "\ni="<<i<<" rem={"<<rem[0]<<","<<rem[1]<<"}\n";
  136.                 cout << (j == 0 ? 'A' : 'B');
  137.                 prev_j = j;
  138.                 found = true;
  139.                 break;
  140.             }
  141.         }
  142.         if (!found) {
  143.             //cout << "\ni="<<i<<" didnt find\n";
  144.             if (i == 1) {
  145.                 cout << -1 << '\n';
  146.                 return 0;
  147.             } else {
  148.                 while (true) {}
  149.             }
  150.         }
  151.     }
  152.     //cout << "\n{"<<rem[0]<<","<<rem[1]<<"}\n";
  153. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement