Advertisement
Dang_Quan_10_Tin

GPICTURES

Jun 18th, 2022
1,159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.82 KB | None | 0 0
  1. #define task "GPICTURES"
  2. #include <iostream>
  3. #include <cstdio>
  4. #include <algorithm>
  5. #include <vector>
  6. #include <queue>
  7. #include <map>
  8.  
  9. using namespace std;
  10.  
  11. using ll = long long;
  12. using ld = long double;
  13.  
  14. constexpr int N = 1e6 + 5;
  15.  
  16. #define Find(x, v) (lower_bound(x.begin(), x.end(), v) - x.begin() + 1)
  17. void Read();
  18. void Compress();
  19.  
  20. struct FenwickTree
  21. {
  22.     vector<int> a;
  23.     int n;
  24.  
  25.     void Assign(int m)
  26.     {
  27.         this->n = m;
  28.         a.assign(m + 2, 0);
  29.     }
  30.  
  31.     void Update(int p, int v)
  32.     {
  33.         for (; p <= n; p += p & -p)
  34.             a[p] += v;
  35.     }
  36.  
  37.     int Get(int p)
  38.     {
  39.         int ans(0);
  40.         for (; p; p -= p & -p)
  41.             ans += a[p];
  42.         return ans;
  43.     }
  44.  
  45.     int Get(int l, int r)
  46.     {
  47.         return Get(r) - Get(l - 1);
  48.     }
  49. };
  50.  
  51. struct Count
  52. {
  53.     FenwickTree g;
  54.     vector<int> s;
  55.  
  56.     void Build()
  57.     {
  58.         sort(s.begin(), s.end());
  59.         s.resize(unique(s.begin(), s.end()) - s.begin());
  60.         g.Assign(s.size());
  61.     }
  62.  
  63.     inline void Update(int v, int c)
  64.     {
  65.         g.Update(Find(s, v), c);
  66.     }
  67.  
  68.     inline void Insert(int v)
  69.     {
  70.         Update(v, 1);
  71.     }
  72.     inline void Delete(int v)
  73.     {
  74.         Update(v, -1);
  75.     }
  76.  
  77.     int Get(int l, int r)
  78.     {
  79.         return g.Get(Find(s, l), Find(s, r + 1) - 1);
  80.     }
  81. } f[N];
  82.  
  83. struct SegmentTree
  84. {
  85.     vector<pair<int, int>> st;
  86.     int n;
  87.  
  88.     pair<int, int> Merge(const pair<int, int> &a, const pair<int, int> &b)
  89.     {
  90.         if (a.second == b.second)
  91.             return make_pair(a.first + b.first, a.second);
  92.         else if (a.first > b.first)
  93.             return make_pair(a.first - b.first, a.second);
  94.         else if (a.first < b.first)
  95.             return make_pair(b.first - a.first, b.second);
  96.         return make_pair(0, 0);
  97.     }
  98.  
  99.     void Build(int id, int l, int r, pair<int, int> a[N])
  100.     {
  101.         if (l == r)
  102.         {
  103.             st[id] = a[l];
  104.             return;
  105.         }
  106.         Build(id << 1, l, (l + r) / 2, a);
  107.         Build(id << 1 | 1, (l + r) / 2 + 1, r, a);
  108.  
  109.         st[id] = Merge(st[id << 1], st[id << 1 | 1]);
  110.     }
  111.  
  112.     void Build(int n, pair<int, int> a[N])
  113.     {
  114.         this->n = n;
  115.         st.assign(n * 4 + 5, {0, 0});
  116.  
  117.         Build(1, 1, n, a);
  118.     }
  119.  
  120.     pair<int, int> Get(int id, int l, int r, const int &a, const int &b)
  121.     {
  122.         if (l > b || r < a)
  123.             return {0, 0};
  124.         if (l >= a && r <= b)
  125.             return st[id];
  126.  
  127.         return Merge(Get(id << 1, l, (l + r) / 2, a, b), Get(id << 1 | 1, (l + r) / 2 + 1, r, a, b));
  128.     }
  129.  
  130.     pair<int, int> Get(int l, int r)
  131.     {
  132.         return Get(1, 1, n, l, r);
  133.     }
  134. } row[N], sweep;
  135.  
  136. int m, n, h, w;
  137. vector<int> a[N], compress;
  138. pair<int, int> represent[N];
  139.  
  140. void Solve()
  141. {
  142.     for (int i = 1; i <= m; ++i)
  143.     {
  144.         for (int j = 1; j <= n; ++j)
  145.         {
  146.             f[a[i][j]].s.emplace_back(i);
  147.             represent[j] = make_pair(1, a[i][j]);
  148.         }
  149.         row[i].Build(n, represent);
  150.     }
  151.  
  152.     for (int i = 1; i <= m * n; ++i)
  153.         f[i].Build();
  154.  
  155.     ll ans(0);
  156.  
  157.     for (int i = 1; i <= n; ++i)
  158.     {
  159.         for (int j = 1; j <= m; ++j)
  160.         {
  161.             if (i > w)
  162.                 f[a[j][i - w]].Delete(j);
  163.  
  164.             f[a[j][i]].Insert(j);
  165.         }
  166.  
  167.         if (i >= w)
  168.         {
  169.             for (int j = 1; j <= m; ++j)
  170.                 represent[j] = row[j].Get(i - w + 1, i);
  171.             sweep.Build(m, represent);
  172.  
  173.             for (int j = h; j <= m; ++j)
  174.             {
  175.                 pair<int, int> candidate = sweep.Get(j - h + 1, j);
  176.  
  177.                 // cerr << j << " " << i << ": " << candidate.second << " - " << candidate.first << "\n";
  178.  
  179.                 if (candidate.first == 0)
  180.                     ++ans;
  181.                 else
  182.                 {
  183.                     int v = f[candidate.second].Get(j - h + 1, j);
  184.  
  185.                     if (v * 2 <= h * w)
  186.                         ++ans;
  187.                 }
  188.             }
  189.         }
  190.     }
  191.  
  192.     cout << ans;
  193. }
  194.  
  195. int32_t main()
  196. {
  197.     ios_base::sync_with_stdio(0);
  198.     cin.tie(0);
  199.     cout.tie(0);
  200.  
  201.     if (fopen(task ".INP", "r"))
  202.     {
  203.         freopen(task ".INP", "r", stdin);
  204.         freopen(task ".OUT", "w", stdout);
  205.     }
  206.  
  207.     Read();
  208.     Compress();
  209.     Solve();
  210. }
  211.  
  212. void Read()
  213. {
  214.     cin >> m >> n >> h >> w;
  215.  
  216.     for (int i = 1; i <= m; ++i)
  217.     {
  218.         a[i].assign(n + 1, 0);
  219.         for (int j = 1; j <= n; ++j)
  220.         {
  221.             cin >> a[i][j];
  222.             compress.emplace_back(a[i][j]);
  223.         }
  224.     }
  225. }
  226.  
  227. void Compress()
  228. {
  229.     sort(compress.begin(), compress.end());
  230.     compress.resize(unique(compress.begin(), compress.end()) - compress.begin());
  231.  
  232.     for (int i = 1; i <= m; ++i)
  233.         for (int j = 1; j <= n; ++j)
  234.             a[i][j] = Find(compress, a[i][j]);
  235. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement