Advertisement
Guest User

Untitled

a guest
Sep 25th, 2021
290
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.14 KB | None | 0 0
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <queue>
  4. #include <vector>
  5. #include <cassert>
  6. #include <functional>
  7. #include <memory>
  8. #include "../atcoder/segtree"
  9. #include "../atcoder/lazysegtree.hpp"
  10.  
  11. using namespace std;
  12.  
  13. typedef pair<int, int> ii;
  14. typedef long long int64;
  15. typedef vector<int> vi;
  16.  
  17. #define pb push_back
  18. #define all(v) (v).begin(),(v).end()
  19. #define sz(v) ((int)(v).size())
  20.  
  21. int IntSum(int x, int y) {
  22.     return x + y;
  23. }
  24.  
  25. int IntMin(int x, int y) {
  26.     return min(x, y);
  27. }
  28.  
  29. int IntZero() {
  30.     return 0;
  31. }
  32.  
  33. int IntInf() {
  34.     return 1000 * 1000 * 1000;
  35. }
  36.  
  37. using MegaTree = atcoder::lazy_segtree<int, IntMin, IntInf, int, IntSum, IntSum, IntZero>;
  38.  
  39. struct DownSolver {
  40.     vector<vi> a;
  41.     int k;
  42.     int n, m;
  43.     vector<unique_ptr<atcoder::segtree<int, IntSum, IntZero>>> topk;
  44.     unique_ptr<MegaTree> rows;
  45.  
  46.     void Flip(int x, int y) {
  47.         int cur_sum = topk[y]->prod(0, x + 2);
  48.         int l = topk[y]->max_right(0, [this](int x) { return x <= this->k; }) - 1;
  49.         int delta = a[x][y] == 1 ? -1 : 1;
  50.         a[x][y] = 1 - a[x][y];
  51.         topk[y]->set(x + 1, a[x][y]);
  52.         int r = topk[y]->max_right(0, [this](int x) { return x <= this->k; }) - 1;
  53.         assert(l >= 0);
  54.         assert(r >= 0);
  55.         if (delta == 1) {
  56.             if (r < n && a[r][y]) ++r;
  57.             if (l > 0 && l < n && a[l - 1][y]) --l;
  58.             if (l > r) {
  59.                 rows->apply(r + 1, l + 1, delta);
  60.             }
  61.             if ((x < r || x >= l) && cur_sum <= k) {
  62.                 rows->apply(x + 1, x + 2, delta);
  63.             }
  64.         } else {
  65.             if (r < n && r > 0 && a[r - 1][y]) --r;
  66.             if (l < n && a[l][y]) ++l;
  67.             if (r > l)
  68.                 rows->apply(l + 1, r + 1, delta);
  69.             if ((x < l || x >= r) && cur_sum <= k + 1) {
  70.                 rows->apply(x + 1, x + 2, delta);
  71.             }
  72.         }
  73.     }
  74.  
  75.     void Init(const vector<vi>& _a, int _k) {
  76.         this->a = _a;
  77.         this->k = _k;
  78.         n = sz(a);
  79.         m = sz(a[0]);
  80.         rows.reset(new MegaTree(n + 10));
  81.         for (int i = 0; i < m; ++i) {
  82.             auto* tree = new atcoder::segtree<int, IntSum, IntZero>(n + 10);
  83.             topk.emplace_back(unique_ptr<atcoder::segtree<int, IntSum, IntZero>>(tree));
  84.         }
  85.         a.push_back(vi(m, 0));
  86.         vi sum(m, 0);
  87.         for (int i = 0; i <= n; ++i) {
  88.             for (int j = 0; j < m; ++j) {
  89.                 if (a[i][j]) {
  90.                     topk[j]->set(i + 1, 1);
  91.                 }
  92.             }
  93.             if (i < n) {
  94.                 for (int j = 0; j < m; ++j)
  95.                     sum[j] += a[i][j];
  96.             }
  97.             if (i >= k) {
  98.                 int cur = i - k;
  99.                 for (int j = 0; j < m; ++j) {
  100.                     if (a[i][j] || sum[j] > k) ++cur;
  101.                 }
  102.                 rows->set(i + 1, cur);
  103.             }
  104.         }
  105.     }
  106.  
  107.     int Res() const {
  108.         return min(m + 1, rows->prod(0, n + 2));
  109.     }
  110. };
  111.  
  112. class TaskC {
  113. public:
  114.     void solve(std::istream& in, std::ostream& out) {
  115.         int num_tests;
  116.         in >> num_tests;
  117.         for (int i = 0; i < num_tests; ++i) {
  118.             cerr << "Case " << i << "\n";
  119.             cerr.flush();
  120.             out << "Case #" << (i + 1) << ": ";
  121.             doSolve(in, out);
  122.         }
  123.     }
  124.  
  125.     vector<vi> a;
  126.  
  127.     void doSolve(std::istream& in, std::ostream& out) {
  128.         int n, m, k, q;
  129.         in >> n >> m >> k >> q;
  130.         --k;
  131.         a = vector<vi>(n, vi(m, 0));
  132.         for (int i = 0; i < n; ++i) {
  133.             string s;
  134.             in >> s;
  135.             for (int j = 0; j < m; ++j) {
  136.                 a[i][j] = (s[j] == 'X' ? 1 : 0);
  137.             }
  138.         }
  139.         DownSolver straight, rev;
  140.         straight.Init(a, k);;
  141.         reverse(all(a));
  142.         rev.Init(a, n - k - 1);
  143.         int64 res = 0;
  144.         for (int i = 0; i < q; ++i) {
  145.             int x, y;
  146.             in >> x >> y;
  147.             --x, --y;
  148.             straight.Flip(x, y);
  149.             rev.Flip(n - x - 1, y);
  150.             res += min(straight.Res(), rev.Res());
  151.         }
  152.         out << res << "\n";
  153.     }
  154. };
  155.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement