제출 #1182387

#제출 시각아이디문제언어결과실행 시간메모리
1182387jerzykRoad Service 2 (JOI24_ho_t5)C++20
0 / 100
40 ms8516 KiB
#include <bits/stdc++.h> using namespace std; #define pb push_back #define st first #define nd second typedef long long ll; typedef long double ld; const ll I = 1000'000'000'000'000'000LL; const int II = 2'000'000'000; const ll M = 1000'000'007LL; const int N = 1<<18; int tab[N], cst[N], lst1[N], lst2[N], whend[N]; int fau[N], l[N], r[N], h[N]; int czy[N]; vector<int> aktz; int pos[N]; pair<int, int> ran[N]; int akt[N]; int k = 0; int dp[N]; int Find(int a) { if(fau[a] == a) return a; return (fau[a] = Find(fau[a])); } void Union(int a, int b) { fau[Find(b)] = Find(a); } void DoR(int n, int m) { vector<pair<pair<int, int>, int>> aktr; for(int i = 1; i <= n * m; ++i) { if(fau[i] != i) continue; aktr.pb(make_pair(make_pair(r[i], l[i]), i)); whend[l[i]] = max(whend[l[i]], r[i]); } for(int i = 1; i <= n; ++i) whend[i] = max(whend[i], whend[i - 1]); sort(aktr.begin(), aktr.end()); k = (int)aktr.size(); for(int i = 1; i <= k; ++i) { ran[i] = aktr[i - 1].st; swap(ran[i].st, ran[i].nd); pos[aktr[i - 1].nd] = i; } } void DoQ(int n, int m) { int a, b, il, q = 0; cin >> il; for(int i = 1; i <= il; ++i) { cin >> a >> b; int x = (a - 1) * m + b; x = Find(x); if(czy[x]) continue; czy[x] = 1; aktz.pb(x); ++q; akt[q] = pos[x]; } for(int i = 0; i < (int)aktz.size(); ++i) czy[aktz[i]] = 0; aktz.clear(); sort(akt + 1, akt + 1 + q); //cout << "\nQ:\n"; //for(int i = 1; i <= q; ++i) //cout << ran[akt[i]].st << " " << ran[akt[i]].nd << "\n"; int s1 = 0, s2 = ran[akt[1]].nd, ct1 = 0, ct2 = 0, ans = 0, lend = ran[akt[1]].st; if(q == 1) { cout << 0 << "\n"; return; } /*if(lst1[s2] < ran[akt[1]].st) { ans = 2; ct1 = ran[akt[1]].nd; s1 = whend[s1]; ct2 = ct1; s2 = s1; }*/ for(int i = 1; i <= q; ++i) { if(i > 1) lend = min(lend, ran[akt[i - 1]].st); //cout << "\nS: C1: " << ct1 << " " << s1 << " C2: " << ct2 << " " << s2 << " ans: " << ans << "\n"; ct2 = max(ct2, lst1[min(s1, ran[akt[i]].nd)]); s2 = max(s2, whend[ct2]); int nct1 = 0, nct2 = 0; int v = akt[i]; //cout << "S: C1: " << ct1 << " " << s1 << " C2: " << ct2 << " " << s2 << " ans: " << ans << "\n"; while(s2 < ran[v].st) { ++ans; nct1 = ct2; nct1 = max(nct1, lst1[s1]); nct2 = lst1[s2]; nct2 = max(nct2, lst2[s1]); nct2 = max(nct2, nct1); ct1 = nct1; ct2 = nct2; if(s1 >= whend[ct1] && s2 >= whend[ct2]) { cout << -1 << "\n"; return; } s1 = max(s1, whend[ct1]); s2 = max(s2, whend[ct2]); } //cout << "M: C1: " << ct1 << " " << s1 << " C2: " << ct2 << " " << s2 << " ans: " << ans << "\n"; if(s2 >= ran[v].nd) { if(s1 < ran[v].st) { ++ans; nct2 = max(lst1[min(ran[v].nd, s2)], lst2[min(ran[v].nd, s1)]); ct1 = ct2; s1 = s2; ct2 = nct2; s2 = whend[ct2]; } //cout << ct1 << " " << ct2 << " " << ans << "\n"; if(ct2 >= ran[v].st) { if(ct1 >= ran[v].st) continue; nct1 = max(ct2, lst1[min(s1, ran[v].nd)]); nct2 = lst2[min(s1, ran[v].nd)]; ct1 = nct1; ct2 = nct2; s1 = whend[ct1]; s2 = whend[ct2]; ++ans; continue; } //if(s1 >= ran[v].nd) //{--ans; s2 = s1; ct2 = ct1;} if(lst1[min(s1, ran[v].nd)] < max(lend, ran[v].st)) { ans += 2; ct1 = max(min(s1, ran[v].nd), lst1[ran[v].nd]); ct2 = ran[v].nd; s1 = whend[ct1]; s2 = whend[ct2]; continue; } ans += 1; nct2 = ran[v].nd; nct1 = max(lst2[min(s1, ran[v].nd)], lst1[ran[v].nd]); ct1 = ran[v].nd; ct2 = ran[v].nd; s1 = whend[ct1]; s2 = whend[ct2]; continue; } //cout << "1: " << ct1 << " " << s1 << " 2: " << ct2 << " " << s2 << "\n"; ans += 2; nct1 = max(lst1[s2], lst2[s1]); ct1 = nct1; s1 = whend[ct1]; nct2 = max(lst1[min(ran[v].nd, s1)], lst2[s2]); ct2 = nct2; s2 = whend[ct2]; if(ct1 < ran[v].st) { ++ans; nct2 = max(ct2, lst1[min(s2, ran[v].nd)]); nct2 = max(nct2, lst2[min(ran[v].nd, s1)]); ct1 = ct2; s1 = s2; ct2 = nct2; s2 = whend[ct2]; } } cout << ans - 1 << "\n"; } void Solve() { int n, m, q; char z; cin >> n >> m >> q; for(int i = 1; i <= n * m; ++i) {fau[i] = i; l[i] = n * m + 1; r[i] = 0;} for(int i = 1; i <= n; ++i) for(int j = 1; j < m; ++j) { cin >> z; if(z == '1') Union((i - 1) * m + j, (i - 1) * m + j + 1); } for(int i = 1; i < n; ++i) for(int j = 1; j <= m; ++j) { cin >> z; if(z == '1') Union((i - 1) * m + j, (i - 1) * m + j + m); } for(int i = 1; i <= n; ++i) { cin >> cst[i]; lst1[i] = lst1[i - 1]; lst2[i] = lst2[i - 1]; if(cst[i] == 1) lst1[i] = i; else lst2[i] = i; lst2[i] = max(lst2[i], lst1[i]); } for(int i = 1; i <= n; ++i) for(int j = 1; j <= m; ++j) { int x = (i - 1) * m + j; x = Find(x); l[x] = min(l[x], i); r[x] = max(r[x], i); h[x] = max(h[x], j); } DoR(n, m); for(int i = 1; i <= q; ++i) DoQ(n, m); } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); //int t; cin >> t; //while(t--) Solve(); 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...