Submission #1180805

#TimeUsernameProblemLanguageResultExecution timeMemory
1180805niepamietamhaslaRoad Service 2 (JOI24_ho_t5)C++20
10 / 100
449 ms240660 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; #define pi pair<int,int> struct d{ int mi = 1e9; int ma = 0; }; vector<d> przedzialy; const int MAXN = 1e6 + 5; const int MAXK = 20; struct trzy{ int w1; int w2; int w3; }; trzy nxt[MAXN][MAXK]; void dfs(int a, int b, int nr, vector<vector<int>> &kolorek, vector<vector<vector<pair<int,int>>>> &graf){ if(kolorek[a][b] != -1) return; kolorek[a][b] = nr; przedzialy[nr].mi = min(przedzialy.back().mi, a); przedzialy[nr].ma = max(przedzialy.back().ma, a); for(auto u : graf[a][b]){ if(kolorek[u.first][u.second] == -1) dfs(u.first, u.second, nr, kolorek, graf); } return; } int koszt[MAXN]; pair<int,int> poprzedni[MAXN]; pair<int,int> nastepny[MAXN]; int reach[MAXN]; bool czy = true; trzy merge(trzy a, int i){ trzy odp; if(czy == false){ odp.w1 = max(nxt[a.w1][i].w2, nxt[a.w2][i].w1); odp.w2 = max(nxt[a.w2][i].w2, nxt[a.w1][i].w3); odp.w2 = max(odp.w2, nxt[a.w3][i].w1); odp.w3 = max(nxt[a.w2][i].w3, nxt[a.w3][i].w2); } else{ odp.w1 = nxt[a.w1][i].w1; odp.w2 = nxt[a.w1][i].w2; odp.w3 = nxt[a.w1][i].w3; } return odp; } int jmp(int start, pair<int,int> doc, int n){ if(poprzedni[min(reach[start], doc.second)].first >= doc.first) return 1; if(poprzedni[min(reach[start], doc.second)].second >= doc.first) return 2; int w = 0; czy = true; trzy curr = {start, start, start}; for(int i = 19; i >= 0; --i){ trzy tmp = merge(curr, i); //cout << i << " i\n"; //cout << curr.w1 << " " << curr.w2 << " " << curr.w3 << " curr\n"; //cout << tmp.w1 << " " << tmp.w2 << " " << tmp.w3 << " tmp\n"; if(reach[tmp.w2] >= doc.first or tmp.w2 == curr.w2) continue; w += (1 << i); czy = false; curr = tmp; } int tmp1 = nxt[curr.w1][0].w2; //cout << tmp1 << " za 1\n"; if(czy == false and tmp1 != n+1 and poprzedni[min(reach[tmp1], doc.second)].first >= doc.first){ return w + 1; } else if(czy == false and tmp1 != n+1 and poprzedni[min(reach[tmp1], doc.second)].second >= doc.first){ return w + 2; } tmp1 = nxt[curr.w1][0].w3; //cout << tmp1 << " za 2\n"; if(czy == false and tmp1 != n+1 and poprzedni[min(reach[tmp1], doc.second)].first >= doc.first){ return w + 2; } //cout << w << " po jmp\n"; tmp1 = nxt[curr.w2][0].w2; //cout << tmp1 << " za 1\n"; if(tmp1 != n+1 and poprzedni[min(reach[tmp1], doc.second)].first >= doc.first){ return w + 2; } else if(tmp1 != n+1 and poprzedni[min(reach[tmp1], doc.second)].second >= doc.first){ return w + 3; } tmp1 = nxt[curr.w1][0].w3; if(czy == false and tmp1 != n+1 and poprzedni[min(reach[tmp1], doc.second)].second >= doc.first){ return w + 3; } tmp1 = nxt[curr.w2][0].w3; //cout << tmp1 << " za 2\n"; if(tmp1 != n+1 and poprzedni[min(reach[tmp1], doc.second)].first >= doc.first){ return w + 3; } else if(tmp1 != n+1 and poprzedni[min(reach[tmp1], doc.second)].second >= doc.first){ return w + 4; } return 1e9; } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int n, m, q; cin >> n >> m >> q; vector<vector<int>> kolorek; vector<vector<vector<pair<int,int>>>> graf; kolorek.resize(n + 1); graf.resize(n + 1); for(int i = 0; i <= n; ++i){ kolorek[i].resize(m + 1); graf[i].resize(m + 1); } for(int i = 0; i <= n; ++i){ for(int j = 0; j <= m; ++j){ kolorek[i][j] = -1; graf[i][j].clear(); } } char x; string s; for(int i = 1; i <= n; ++i){ cin >> s; for(int j = 1; j < m; ++j){ x = s[j-1]; //cout << x << " x\n"; if(x == '1') { graf[i][j].push_back({i,j+1}); graf[i][j+1].push_back({i,j}); } } } //cout << "#\n"; for(int i = 1; i < n; ++i){ cin >> s; for(int j = 1; j <= m; ++j){ x = s[j-1]; if(x == '1') { graf[i][j].push_back({i + 1, j}); graf[i+1][j].push_back({i,j}); } } } int nr = 1; przedzialy.push_back((d){1000000000, 1000000000}); for(int i = 1; i <= n; ++i){ for(int j = 1; j <= m; ++j){ if(kolorek[i][j] == -1){ przedzialy.push_back((d){i, i}); dfs(i, j, nr, kolorek, graf); nr++; } } } int p1 = -1; int p2 = -1; for(int i = 1; i <= n; ++i){ cin >> koszt[i]; if(koszt[i] == 1){ p1 = i; } else{ p2 = i; } poprzedni[i] = {p1, p2}; //cout << i << " " << poprzedni[i].first << " " << poprzedni[i].second << " poprzednie\n"; } p1 = n+1; p2 = n+1; for(int i = n; i > 0; --i){ if(koszt[i] == 1){ p1 = i; } else{ p2 = i; } nastepny[i] = {p1, p2}; } for(int i = n; i > 0; --i){ reach[i] = i; for(int j = 1; j <= m; ++j){ reach[i] = max(reach[i], przedzialy[kolorek[i][j]].ma); } // if(i == 1){ // cout << reach[i] << " " << poprzedni[reach[i]].second << " rp\n"; // } nxt[i][0].w1 = i; nxt[i][0].w2 = max(i, poprzedni[reach[i]].first); if(poprzedni[reach[i]].first <= i){ //cout << "#\n"; nxt[i][0].w2 = 0; } // if(i == 1){ // cout << nxt[i][0].w2 << " w2\n"; // } nxt[i][0].w3 = max(i, poprzedni[reach[i]].second); if(poprzedni[reach[i]].second <= i){ nxt[i][0].w3 = 0; } nxt[i][0].w3 = max(nxt[i][0].w3, nxt[nxt[i][0].w2][0].w2); } for(int l = 1; l <= 19; ++l){ for(int i = 1; i <= n; ++i){ nxt[i][l].w1 = max(nxt[nxt[i][l-1].w1][l-1].w2, nxt[nxt[i][l-1].w2][l-1].w1); nxt[i][l].w2 = max(nxt[nxt[i][l-1].w1][l-1].w3, nxt[nxt[i][l-2].w2][l-1].w2); nxt[i][l].w2 = max(nxt[i][l].w2, nxt[nxt[i][l-1].w3][l-1].w1); nxt[i][l].w3 = max(nxt[nxt[i][l-1].w3][l-1].w2, nxt[nxt[i][l-1].w2][l-1].w3); } } reach[n+1] = n+1; for(int i = 1; i <= n; ++i){ int prev = -1; for(int l = 0; l <= 19; ++l){ if(nxt[i][l].w1 == 0) nxt[i][l].w1 = n+1; if(nxt[i][l].w2 == 0) nxt[i][l].w2 = n+1; if(nxt[i][l].w3 == 0) nxt[i][l].w3 = n+1; if(nxt[i][l].w2 < prev){ nxt[i][l].w2 = n+1; } else if(nxt[i][l].w2 != n+1){ prev = nxt[i][l].w2; } } } //cout << nxt[1][0].w1 << " " << nxt[1][0].w2 << " " << nxt[1][0].w2 << " nxt\n"; int r; pair<int,int> a; pair<int,int> b; for(int i = 0; i < q; ++i){ cin >> r; if(r != 2) exit(0); cin >> a.first >> a.second; cin >> b.first >> b.second; if(kolorek[a.first][a.second] == kolorek[b.first][b.second]){ cout << 0 << " \n"; continue; } a = {przedzialy[kolorek[a.first][a.second]].mi, przedzialy[kolorek[a.first][a.second]].ma}; b = {przedzialy[kolorek[b.first][b.second]].mi, przedzialy[kolorek[b.first][b.second]].ma}; if(a.second > b.second){ swap(a, b); } //cout << a.first << " " << a.second << " a\n"; //cout << b.first << " " << b.second << " b\n"; if(poprzedni[a.second].first >= max(a.first, b.first)){ cout << 1 << " \n"; continue; } else if(poprzedni[a.second].second >= max(a.first, b.first)){ cout << 2 << " \n"; continue; } int w = 1e9; if(poprzedni[a.second].first >= a.first){ int v = jmp(poprzedni[a.second].first, b, n); //cout << v << " v\n"; w = min(w, v + 1); } if(poprzedni[a.second].second >= a.first){ w = min(w, jmp(poprzedni[a.second].second, b, n) + 2); } if(w > 2 * n){ cout << -1 << " \n"; } else{ cout << w << " \n"; } } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...