#include <bits/stdc++.h> #define PB push_back #define ST first #define ND second #define _ ios_base::sync_with_stdio(0); cin.tie(0); //mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count()); using namespace std; using ll = long long; using pi = pair<int,int>; using vi = vector<int>; const int nax = 500 * 1000 + 10, mod = 1e9 + 7, INF = 1e9; int n; int a[nax], b[nax]; pi ga[nax], gb[nax]; int mi[nax], mx[nax], dp[nax], sz[nax], R[nax]; int ra, rb; bool done[nax]; void dfs(int x) { if(ga[x].ST != 0) dfs(ga[x].ST); if(ga[x].ND != 0) dfs(ga[x].ND); sz[x] = 1 + sz[ga[x].ST] + sz[ga[x].ND]; mi[x] = x; mx[x] = x; if(a[x] > x) { dp[x] = (dp[ga[x].ST] + dp[ga[x].ND] + sz[ga[x].ND])%mod; } else { dp[x] = (dp[ga[x].ST] + dp[ga[x].ND] + sz[ga[x].ST])%mod; } mi[x] = min(mi[x], mi[ga[x].ST]); mx[x] = max(mx[x], mx[ga[x].ND]); } int ustal(int root) { if(root == 0) return 0; int x = root; int y = root; vi path = {}; //~ cout << root << " " << R[root] << "\n"; //~ cout << x << " " << a[x] << "\n"; while(!done[x] && x != R[root]) { path.PB(x); x = a[x]; //~ cout << x << "\n"; if(!done[x] && x != R[root]) y = x; } //~ cout << "PATH: "; //~ for(int z : path) cout << z << " "; //~ cout << "\n"; int ans = 0; if(done[root]) { R[gb[root].ST] = root - 1; R[gb[root].ND] = root + 1; ans += abs(R[root] - root); } else { if(root < R[root]) { ans += (R[root] - root); int p = root, k = R[root], ost = -1;//R[root]; while((int)path.size() > 0 && a[path.back()] > path.back()) { ans = (ans + sz[ga[path.back()].ND] + dp[ga[path.back()].ND])%mod; p = min(p, mi[ga[path.back()].ND]); ost = path.back(); path.pop_back(); } //~ cout << "HERE: " << ost << " " << p << " " << k << "\n"; a[ost] = p; //jeszcze trzeba ustawić rodzica a[p] = p +1; a[k] = k - 1; for(int i = p + 1; i < k; ++i) { if(done[i]) break; done[i] = 1; } R[gb[root].ST] = (p != root ? root - 1 : (ost == root ? ga[root].ST : ost)); R[gb[root].ND] = root + 1; ga[p].ND = 0; ga[k].ST = 0; ga[p].ST = ost; ga[ost].ND = 0; } else if(R[root] < root) { ans += root - R[root]; int p = R[root], k = root, ost = -1; while((int)path.size() > 0 && a[path.back()] < path.back()) { ans = (ans + sz[ga[path.back()].ST] + dp[ga[path.back()].ST])%mod; k = max(k, mx[ga[path.back()].ST]); ost = path.back(); path.pop_back(); } a[ost] = k; for(int i = k - 1; i > p; --i) { if(done[i]) break; done[i] = 1; } //~ cout << "K : " << p << " " << k << " " << ost << " " << root << " " << ga[root].ND << "\n"; R[gb[root].ST] = root - 1; R[gb[root].ND] = (k != root ? root + 1 : (ost == root ? ga[root].ND : ost)); a[k] = k - 1; a[p] = p + 1; ga[p].ND = 0; ga[k].ST = 0; ga[k].ND = ost; ga[ost].ST = 0; } else { R[gb[root].ST] = ga[root].ST; R[gb[root].ND] = ga[root].ND; } } //~ cout << root << " " << R[root] << " " << ans << "\n"; //~ cout << "DONE: "; //~ for(int i = 1; i <= n; ++i) { //~ cout << done[i] << " "; //~ } //~ cout << "\n"; return (ustal(gb[root].ST) + ustal(gb[root].ND) + ans)%mod; } int main() {_ cin >> n; mi[0] = INF; mx[0] = -INF; for(int i = 1; i <= n; ++i) { cin >> a[i]; if(a[i] == -1) ra = i; else { if(a[i] > i) ga[a[i]].ST = i; else ga[a[i]].ND = i; } } for(int i = 1; i <= n; ++i) { cin >> b[i]; if(b[i] == -1) rb = i; else { if(b[i] > i) gb[b[i]].ST = i; else gb[b[i]].ND = i; } } dfs(ra); R[rb] = ra; cout << ustal(rb); }
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 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | #include <bits/stdc++.h> #define PB push_back #define ST first #define ND second #define _ ios_base::sync_with_stdio(0); cin.tie(0); //mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count()); using namespace std; using ll = long long; using pi = pair<int,int>; using vi = vector<int>; const int nax = 500 * 1000 + 10, mod = 1e9 + 7, INF = 1e9; int n; int a[nax], b[nax]; pi ga[nax], gb[nax]; int mi[nax], mx[nax], dp[nax], sz[nax], R[nax]; int ra, rb; bool done[nax]; void dfs(int x) { if(ga[x].ST != 0) dfs(ga[x].ST); if(ga[x].ND != 0) dfs(ga[x].ND); sz[x] = 1 + sz[ga[x].ST] + sz[ga[x].ND]; mi[x] = x; mx[x] = x; if(a[x] > x) { dp[x] = (dp[ga[x].ST] + dp[ga[x].ND] + sz[ga[x].ND])%mod; } else { dp[x] = (dp[ga[x].ST] + dp[ga[x].ND] + sz[ga[x].ST])%mod; } mi[x] = min(mi[x], mi[ga[x].ST]); mx[x] = max(mx[x], mx[ga[x].ND]); } int ustal(int root) { if(root == 0) return 0; int x = root; int y = root; vi path = {}; //~ cout << root << " " << R[root] << "\n"; //~ cout << x << " " << a[x] << "\n"; while(!done[x] && x != R[root]) { path.PB(x); x = a[x]; //~ cout << x << "\n"; if(!done[x] && x != R[root]) y = x; } //~ cout << "PATH: "; //~ for(int z : path) cout << z << " "; //~ cout << "\n"; int ans = 0; if(done[root]) { R[gb[root].ST] = root - 1; R[gb[root].ND] = root + 1; ans += abs(R[root] - root); } else { if(root < R[root]) { ans += (R[root] - root); int p = root, k = R[root], ost = -1;//R[root]; while((int)path.size() > 0 && a[path.back()] > path.back()) { ans = (ans + sz[ga[path.back()].ND] + dp[ga[path.back()].ND])%mod; p = min(p, mi[ga[path.back()].ND]); ost = path.back(); path.pop_back(); } //~ cout << "HERE: " << ost << " " << p << " " << k << "\n"; a[ost] = p; //jeszcze trzeba ustawić rodzica a[p] = p +1; a[k] = k - 1; for(int i = p + 1; i < k; ++i) { if(done[i]) break; done[i] = 1; } R[gb[root].ST] = (p != root ? root - 1 : (ost == root ? ga[root].ST : ost)); R[gb[root].ND] = root + 1; ga[p].ND = 0; ga[k].ST = 0; ga[p].ST = ost; ga[ost].ND = 0; } else if(R[root] < root) { ans += root - R[root]; int p = R[root], k = root, ost = -1; while((int)path.size() > 0 && a[path.back()] < path.back()) { ans = (ans + sz[ga[path.back()].ST] + dp[ga[path.back()].ST])%mod; k = max(k, mx[ga[path.back()].ST]); ost = path.back(); path.pop_back(); } a[ost] = k; for(int i = k - 1; i > p; --i) { if(done[i]) break; done[i] = 1; } //~ cout << "K : " << p << " " << k << " " << ost << " " << root << " " << ga[root].ND << "\n"; R[gb[root].ST] = root - 1; R[gb[root].ND] = (k != root ? root + 1 : (ost == root ? ga[root].ND : ost)); a[k] = k - 1; a[p] = p + 1; ga[p].ND = 0; ga[k].ST = 0; ga[k].ND = ost; ga[ost].ST = 0; } else { R[gb[root].ST] = ga[root].ST; R[gb[root].ND] = ga[root].ND; } } //~ cout << root << " " << R[root] << " " << ans << "\n"; //~ cout << "DONE: "; //~ for(int i = 1; i <= n; ++i) { //~ cout << done[i] << " "; //~ } //~ cout << "\n"; return (ustal(gb[root].ST) + ustal(gb[root].ND) + ans)%mod; } int main() {_ cin >> n; mi[0] = INF; mx[0] = -INF; for(int i = 1; i <= n; ++i) { cin >> a[i]; if(a[i] == -1) ra = i; else { if(a[i] > i) ga[a[i]].ST = i; else ga[a[i]].ND = i; } } for(int i = 1; i <= n; ++i) { cin >> b[i]; if(b[i] == -1) rb = i; else { if(b[i] > i) gb[b[i]].ST = i; else gb[b[i]].ND = i; } } dfs(ra); R[rb] = ra; cout << ustal(rb); } |