// Marcin Knapik // Potyczki algorytmiczne - runda 5. zadanie B1 #include<bits/stdc++.h> using namespace std; #define f first #define s second #define sz(s) (int)s.size() #define all(s) s.begin(), s.begin() #define pb push_back #define mp make_pair #define ii pair<int, int> #define ll long long #define vi vector<int> #define vvi vector<vi> const int mod = 1e9 + 7; int n; int kier(int w, int ojciec){ if(ojciec == -1) return -1; return w < ojciec; } struct drzewo{ int korzen; vi ojciec; vi syn[2]; drzewo(){ ojciec = vi(n); for(int i = 0; i < 2; i++) syn[i] = vi(n, -1); for(int i = 0; i < n; i++){ cin >> ojciec[i]; ojciec[i] -= (ojciec[i] != -1); if(ojciec[i] == -1) korzen = i; else syn[(i < ojciec[i]) ^ 1][ojciec[i]] = i; } } }; ll ans = 0; void podnies(drzewo & tree, int w){ if(tree.syn[kier(w, tree.ojciec[w])][w] != -1) podnies(tree, tree.syn[kier(w, tree.ojciec[w])][w]); assert(tree.syn[kier(w, tree.ojciec[w])][w] == -1); if(kier(w, tree.ojciec[w]) == kier(tree.ojciec[w], tree.ojciec[tree.ojciec[w]])) podnies(tree, tree.ojciec[w]); assert(kier(w, tree.ojciec[w]) != kier(tree.ojciec[w], tree.ojciec[tree.ojciec[w]])); int oj = tree.ojciec[w]; int ki = kier(w, oj); tree.ojciec[w] = tree.ojciec[oj]; tree.ojciec[oj] = w; tree.syn[ki ^ 1][oj] = -1; tree.syn[ki][w] = oj; ans++; } void ukorzen(drzewo & tree, int w){ while(tree.ojciec[w] != -1) podnies(tree, w); } void buduj(drzewo & a, drzewo & b, int korz_a, int korz_b, int pocz = 0, int kon = n - 1){ if(pocz == kon) return; if(korz_a != korz_b) ukorzen(a, korz_b); if(korz_b > pocz){ int sA = a.syn[0][korz_b], sB = b.syn[0][korz_b]; a.ojciec[sA] = -1; b.ojciec[sB] = -1; buduj(a, b, sA, sB, pocz, korz_b - 1); } if(korz_b < kon){ int sA = a.syn[1][korz_b], sB = b.syn[1][korz_b]; a.ojciec[sA] = -1; b.ojciec[sB] = -1; buduj(a, b, sA, sB, korz_b + 1, kon); } } int main(){ ios::sync_with_stdio(0); cin.tie(0); cin >> n; drzewo A, B; buduj(A, B, A.korzen, B.korzen); cout << ans % mod << '\n'; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | // Marcin Knapik // Potyczki algorytmiczne - runda 5. zadanie B1 #include<bits/stdc++.h> using namespace std; #define f first #define s second #define sz(s) (int)s.size() #define all(s) s.begin(), s.begin() #define pb push_back #define mp make_pair #define ii pair<int, int> #define ll long long #define vi vector<int> #define vvi vector<vi> const int mod = 1e9 + 7; int n; int kier(int w, int ojciec){ if(ojciec == -1) return -1; return w < ojciec; } struct drzewo{ int korzen; vi ojciec; vi syn[2]; drzewo(){ ojciec = vi(n); for(int i = 0; i < 2; i++) syn[i] = vi(n, -1); for(int i = 0; i < n; i++){ cin >> ojciec[i]; ojciec[i] -= (ojciec[i] != -1); if(ojciec[i] == -1) korzen = i; else syn[(i < ojciec[i]) ^ 1][ojciec[i]] = i; } } }; ll ans = 0; void podnies(drzewo & tree, int w){ if(tree.syn[kier(w, tree.ojciec[w])][w] != -1) podnies(tree, tree.syn[kier(w, tree.ojciec[w])][w]); assert(tree.syn[kier(w, tree.ojciec[w])][w] == -1); if(kier(w, tree.ojciec[w]) == kier(tree.ojciec[w], tree.ojciec[tree.ojciec[w]])) podnies(tree, tree.ojciec[w]); assert(kier(w, tree.ojciec[w]) != kier(tree.ojciec[w], tree.ojciec[tree.ojciec[w]])); int oj = tree.ojciec[w]; int ki = kier(w, oj); tree.ojciec[w] = tree.ojciec[oj]; tree.ojciec[oj] = w; tree.syn[ki ^ 1][oj] = -1; tree.syn[ki][w] = oj; ans++; } void ukorzen(drzewo & tree, int w){ while(tree.ojciec[w] != -1) podnies(tree, w); } void buduj(drzewo & a, drzewo & b, int korz_a, int korz_b, int pocz = 0, int kon = n - 1){ if(pocz == kon) return; if(korz_a != korz_b) ukorzen(a, korz_b); if(korz_b > pocz){ int sA = a.syn[0][korz_b], sB = b.syn[0][korz_b]; a.ojciec[sA] = -1; b.ojciec[sB] = -1; buduj(a, b, sA, sB, pocz, korz_b - 1); } if(korz_b < kon){ int sA = a.syn[1][korz_b], sB = b.syn[1][korz_b]; a.ojciec[sA] = -1; b.ojciec[sB] = -1; buduj(a, b, sA, sB, korz_b + 1, kon); } } int main(){ ios::sync_with_stdio(0); cin.tie(0); cin >> n; drzewo A, B; buduj(A, B, A.korzen, B.korzen); cout << ans % mod << '\n'; } |