Advertisement
KalininN

FHC 2021 R2 C2

Sep 25th, 2021 (edited)
509
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.47 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. #ifdef LOCAL
  6.     #define eprintf(...) fprintf(stderr, __VA_ARGS__)
  7. #else
  8.     #define eprintf(...) 42
  9. #endif
  10.  
  11. using ll = long long;
  12. using ld = long double;
  13. using D = double;
  14. using uint = unsigned int;
  15. template<typename T>
  16. using pair2 = pair<T, T>;
  17.  
  18. #define pb push_back
  19. #define mp make_pair
  20. #define all(x) (x).begin(),(x).end()
  21. #define fi first
  22. #define se second
  23.  
  24. const int maxn = 2000006;
  25. const int maxtreesize = 1 << 21;
  26.  
  27. pair2<int> tree[2 * maxtreesize];
  28. char s[maxn];
  29. vector<int> wh[maxn];
  30. set<int> setik[maxn];
  31. int kth[maxn];
  32. int answer[maxn];
  33. int n, m, k, nq;
  34. int treesize;
  35. int xq[maxn], yq[maxn];
  36.  
  37. inline int getans(int cur)
  38. {
  39.     return tree[cur].fi + tree[cur].se;
  40. }
  41.  
  42. void add(int cur, int cl, int cr, int l, int r, int t)
  43. {
  44.     if (cl > r || cr < l) return;
  45.     if (cl >= l && cr <= r)
  46.     {
  47.         tree[cur].se += t;
  48.         return;
  49.     }
  50.     int cm = (cl + cr) / 2;
  51.     add(cur * 2, cl, cm, l, r, t);
  52.     add(cur * 2 + 1, cm + 1, cr, l, r, t);
  53.     tree[cur].fi = min(getans(cur * 2), getans(cur * 2 + 1));
  54. }
  55.  
  56. void add(int mxpos, int idx, int t)
  57. {
  58.     //cout << "add " << mxpos << ' ' << idx << ' ' << t << endl;
  59.     if (mxpos >= k && idx < k) add(1, 0, treesize - 1, mxpos - k, mxpos - k, t);
  60.     if (mxpos >= k && idx == k) add(1, 0, treesize - 1, mxpos - k, n - 1, t);
  61. }
  62.  
  63. void solveoneway()
  64. {
  65.     treesize = 1;
  66.     while (treesize < n) treesize *= 2;
  67.     for (int i = 0; i < 2 * treesize; i++)
  68.     {
  69.         tree[i] = {0, 0};
  70.     }
  71.     for (int i = 1; i < n; i++) add(1, 0, treesize - 1, i, i, i);
  72.     add(1, 0, treesize - 1, n, treesize - 1, m + 1);
  73.    
  74.     for (int i = 0; i < m; i++) setik[i].clear();
  75.     for (int i = 0; i < m; i++)
  76.     {
  77.         for (int j = 0; j < (int)wh[i].size(); j++)
  78.         {
  79.             add(wh[i][j], j, 1);
  80.             setik[i].insert(wh[i][j]);
  81.         }
  82.         if ((int)wh[i].size() <= k) kth[i] = n;
  83.         else kth[i] = wh[i][k];
  84.     }
  85.    
  86.     for (int q = 0; q < nq; q++)
  87.     {
  88.         int i = yq[q];
  89.         int x = xq[q];
  90.         //cout << "solve q = " << q << endl;
  91.        
  92.         auto it = setik[i].lower_bound(x);
  93.         if (it != setik[i].end() && *it == x)
  94.         {
  95.             if (x < kth[i])
  96.             {
  97.                 add(x, k - 1, -1);
  98.                 if (kth[i] != n)
  99.                 {
  100.                     add(kth[i], k, -1);
  101.                     add(kth[i], k - 1, 1);
  102.                     auto y = setik[i].upper_bound(kth[i]);
  103.                     if (y != setik[i].end())
  104.                     {
  105.                         kth[i] = *y;
  106.                         add(kth[i], k, 1);
  107.                     } else kth[i] = n;
  108.                 }
  109.             } else if (x == kth[i])
  110.             {
  111.                 add(kth[i], k, -1);
  112.                 auto y = setik[i].upper_bound(kth[i]);
  113.                 if (y != setik[i].end())
  114.                 {
  115.                     kth[i] = *y;
  116.                     add(kth[i], k, 1);
  117.                 } else kth[i] = n;
  118.             } else {}
  119.             setik[i].erase(it);
  120.         } else
  121.         {
  122.             if (x < kth[i])
  123.             {
  124.                 if (kth[i] != n)
  125.                 {
  126.                     if (it != setik[i].end() && *it == kth[i])
  127.                     {
  128.                         add(kth[i], k, -1);
  129.                         kth[i] = x;
  130.                         add(kth[i], k, 1);
  131.                     } else
  132.                     {
  133.                         add(x, k - 1, 1);
  134.                         add(kth[i], k, -1);
  135.                         auto y = prev(setik[i].lower_bound(kth[i]));
  136.                         kth[i] = *y;
  137.                         add(kth[i], k - 1, -1);
  138.                         add(kth[i], k, 1);
  139.                     }
  140.                 } else
  141.                 {
  142.                     if ((int)setik[i].size() == k)
  143.                     {
  144.                         add(x, k - 1, 1);
  145.                         int y = x;
  146.                         if (!setik[i].empty()) y = max(y, *setik[i].rbegin());
  147.                         add(y, k - 1, -1);
  148.                         add(y, k, 1);
  149.                         kth[i] = y;
  150.                     } else
  151.                     {
  152.                         add(x, k - 1, 1);
  153.                     }
  154.                 }
  155.             }
  156.             setik[i].insert(x);
  157.         }
  158.         //cout << getans(1) << endl;
  159.         answer[q] = min(answer[q], getans(1));
  160.     }
  161. }
  162.  
  163. void solve()
  164. {
  165.     scanf("%d%d%d%d", &n, &m, &k, &nq);
  166.     k--;
  167.     for (int i = 0; i < m; i++) wh[i].clear();
  168.     for (int i = 0; i < n; i++)
  169.     {
  170.         scanf("%s", s);
  171.         for (int j = 0; j < m; j++) if (s[j] == 'X') wh[j].pb(i);
  172.     }
  173.     for (int q = 0; q < nq; q++)
  174.     {
  175.         scanf("%d%d", &xq[q], &yq[q]);
  176.         xq[q]--;
  177.         yq[q]--;
  178.     }
  179.    
  180.     for (int i = 0; i < nq; i++) answer[i] = m;
  181.     for (int IT = 0; IT < 2; IT++)
  182.     {
  183.         solveoneway();
  184.         k = n - k - 1;
  185.         for (int i = 0; i < m; i++)
  186.         {
  187.             reverse(all(wh[i]));
  188.             for (auto &t : wh[i]) t = n - t - 1;
  189.         }
  190.         for (int q = 0; q < nq; q++) xq[q] = n - xq[q] - 1;
  191.     }
  192.     ll res = 0;
  193.     for (int i = 0; i < nq; i++) res += answer[i];
  194.     printf("%lld\n", res);
  195. }
  196.  
  197. int main()
  198. {
  199.     int NT = 0;
  200.     scanf("%d", &NT);
  201.     for (int T = 1; T <= NT; T++)
  202.     {
  203.         printf("Case #%d: ", T);
  204.        
  205.         solve();
  206.  
  207.         fprintf(stderr, "%d/%d cases done!\n", T, NT);
  208.     }
  209.     return 0;
  210. }
  211.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement