Submission #914746

#TimeUsernameProblemLanguageResultExecution timeMemory
914746qinFurniture (JOI20_furniture)C++17
100 / 100
299 ms17020 KiB
#include <bits/stdc++.h> #define fi first #define se second #define ssize(x) int(x.size()) #define pn printf("\n"); #define all(x) x.begin(),x.end() #define rall(x) x.rbegin(),x.rend() #define vv vector using namespace std; typedef long long ll; typedef pair<int, int> pii; int inf = 2e09; ll infll = 2e18; int mod = 119<<23|1; void bfs_up(vv<vv<int>> &t, vv<vv<int>> &ed, pii st, vv<set<int>> &s){ queue<pii> q; if(!t[st.fi-1][st.se]) q.emplace(pii(st.fi-1, st.se)); if(!t[st.fi][st.se-1]) q.emplace(pii(st.fi, st.se-1)); while(!q.empty()){ int i = q.front().fi, j = q.front().se; q.pop(); if(!t[i+1][j] || !t[i][j+1] || t[i][j]) continue; // nie musimy usuwać, bo jest przejście t[i][j] = 1; auto it = prev(s[i].upper_bound(j)); // modyfikuję seta, nie sądzę, że muszę sprawdzać czy begin if(*it == j) s[i].erase(it); else ed[i][*it] = j-1; if(!t[i-1][j]) q.emplace(pii(i-1, j)); if(!t[i][j-1]) q.emplace(pii(i, j-1)); } } void bfs_down(vv<vv<int>> &t, vv<vv<int>> &ed, pii st, vv<set<int>> &s){ queue<pii> q; if(!t[st.fi+1][st.se]) q.emplace(pii(st.fi+1, st.se)); if(!t[st.fi][st.se+1]) q.emplace(pii(st.fi, st.se+1)); while(!q.empty()){ int i = q.front().fi, j = q.front().se; q.pop(); if(!t[i-1][j] || !t[i][j-1] || t[i][j]) continue; // nie musimy usuwać, bo jest przejście t[i][j] = 1; auto it = s[i].lower_bound(j); // modyfikuję seta assert(it != s[i].end()); if(ed[i][*it] == j) s[i].erase(it); else{ int tmp = *it; ed[i][*it+1] = ed[i][*it], ed[i][*it] = 0, s[i].erase(it), s[i].emplace(tmp+1); } if(!t[i+1][j]) q.emplace(pii(i+1, j)); if(!t[i][j+1]) q.emplace(pii(i, j+1)); } } void answer(){ int n, m; scanf("%d%d", &n, &m); vv<vv<int>> t(n+2, vv<int>(m+2, 0)), ed(n+2, vv<int>(m+2, 0)); // w e trzymam koniec przedziału, ktory jest na secie vector<pii> red; for(int i = 1; i <= n; ++i){ for(int j = 1, a; j <= m; ++j){ scanf("%d", &a); if(a) red.emplace_back(i, j); } } for(int i = 0; i <= n+1; ++i) t[i][0] = 1, t[i][m+1] = 1; // narożników chyba nie muszę, ale kto wie, zostawiam komentarz for(int j = 1; j <= m; ++j) t[0][j] = 1, t[n+1][j] = 1; vv<set<int>> s(n+2); for(int i = 1; i <= n; ++i) s[i].emplace(1), ed[i][1] = m; for(pii &u : red){ int i = u.fi, j = u.se; if(t[i][j]) continue; auto it = prev(s[i].upper_bound(j)); if(ed[i][*it] != j) ed[i][j+1] = ed[i][*it], s[i].emplace(j+1); it = prev(s[i].upper_bound(j)); if(*it != j) ed[i][*it] = j-1; else s[i].erase(it); t[i][j] = 1; bfs_up(t, ed, pii(i, j), s); bfs_down(t, ed, pii(i, j), s); } int q; scanf("%d", &q); for(++q; --q; ){ int i, j; scanf("%d%d", &i, &j); if(t[i][j]){ printf("1\n"); continue; } if(ssize(s[i]) > 1){ printf("1\n"); auto it = prev(s[i].upper_bound(j)); if(ed[i][*it] != j) ed[i][j+1] = ed[i][*it], s[i].emplace(j+1); it = prev(s[i].upper_bound(j)); if(*it != j) ed[i][*it] = j-1; else s[i].erase(it); t[i][j] = 1; bfs_up(t, ed, pii(i, j), s), bfs_down(t, ed, pii(i, j), s); continue; } bool left = 1, right = 1; auto it = prev(s[i].upper_bound(j)); int it_beg = *it, it_ed = ed[i][*it]; if(*it == j) left = 0; if(it_ed == j) right = 0; if(right){ bool good = 0; it = s[i-1].lower_bound(j+1); if(it != s[i-1].end() && *it <= it_ed) good = 1; if(it != s[i-1].begin() && j+1 <= ed[i-1][*prev(it)]) good = 1; if(!good) right = 0; } if(left){ bool good = 0; it = s[i+1].lower_bound(it_beg); if(it != s[i+1].end() && *it <= j-1) good = 1; if(it != s[i+1].begin() && it_beg <= ed[i+1][*prev(it)]) good = 1; if(!good) left = 0; } if(!left && !right) printf("0\n"); else{ printf("1\n"); it = prev(s[i].upper_bound(j)); if(ed[i][*it] != j) ed[i][j+1] = ed[i][*it], s[i].emplace(j+1); it = prev(s[i].upper_bound(j)); if(*it != j) ed[i][*it] = j-1; else s[i].erase(it); t[i][j] = 1; bfs_up(t, ed, pii(i, j), s), bfs_down(t, ed, pii(i, j), s); } } } int main(){ int T = 1; for(++T; --T; ) answer(); return 0; }

Compilation message (stderr)

furniture.cpp: In function 'void answer()':
furniture.cpp:49:18: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   49 |   int n, m; scanf("%d%d", &n, &m);
      |             ~~~~~^~~~~~~~~~~~~~~~
furniture.cpp:53:42: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   53 |     for(int j = 1, a; j <= m; ++j){ scanf("%d", &a);  if(a) red.emplace_back(i, j); }
      |                                     ~~~~~^~~~~~~~~~
furniture.cpp:72:15: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   72 |   int q; scanf("%d", &q);
      |          ~~~~~^~~~~~~~~~
furniture.cpp:74:20: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   74 |     int i, j; scanf("%d%d", &i, &j);
      |               ~~~~~^~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...