#include <bits/stdc++.h> using namespace std; const int MOD = 1000000007; struct Node { int ch[2]; int size; int cost[2]; }; typedef vector<Node> Tree; void prepareTree(Tree &D, int root) { if (!root) return; int l=D[root].ch[0]; int r=D[root].ch[1]; prepareTree(D, l); prepareTree(D, r); D[root].size=D[l].size+D[r].size+1; D[root].cost[0] = (0LL+ D[l].cost[0] + D[r].cost[1] + D[r].size)%MOD; D[root].cost[1] = (0LL+ D[l].cost[0] + D[r].cost[1] + D[l].size)%MOD; } int bzium(const Tree &D1, int root1, const Tree &D2, int root2) { if (root1==0) return 0; int res=0; (res+=abs(root1-root2))%=MOD; int l1=D1[root1].ch[0]; int r1=D1[root1].ch[1]; int l2=D2[root2].ch[0]; int r2=D2[root2].ch[1]; while (D1[l1].size != D2[l2].size) { if (D1[l1].size > D2[l2].size) { (res+= (D1[ D1[l1].ch[1] ].size + D1[ D1[l1].ch[1] ].cost[1])%MOD )%=MOD; l1=D1[l1].ch[0]; } else { (res+= (D2[ D2[l2].ch[1] ].size + D2[ D2[l2].ch[1] ].cost[1])%MOD )%=MOD; l2=D2[l2].ch[0]; } } while (D1[r1].size != D2[r2].size) { if (D1[r1].size > D2[r2].size) { (res+= (D1[ D1[r1].ch[0] ].size + D1[ D1[r1].ch[0] ].cost[0])%MOD )%=MOD; r1=D1[r1].ch[1]; } else { (res+= (D2[ D2[r2].ch[0] ].size + D2[ D2[r2].ch[0] ].cost[0])%MOD )%=MOD; r2=D2[r2].ch[1]; } } (res+=bzium(D1, l1, D2, l2))%=MOD; (res+=bzium(D1, r1, D2, r2))%=MOD; return res; } int main() { ios::sync_with_stdio(0); cin.tie(0); int n; cin >> n; Tree D1(n+1, {0, 0, 0, 0, 0}); int root1; Tree D2(n+1, {0, 0, 0, 0, 0}); int root2; for (int i=1; i<=n; i++) { int x; cin >> x; ((x==-1)?root1:D1[x].ch[x<i])=i; } for (int i=1; i<=n; i++) { int x; cin >> x; ((x==-1)?root2:D2[x].ch[x<i])=i; } prepareTree(D1, root1); // for (int i=1; i<=n; i++) cout << i << " " << D1[i].size << " " << D1[i].cost[0] << " " << D1[i].cost[1] << endl; prepareTree(D2, root2); cout << bzium(D1, root1, D2, root2) << endl; return 0; }
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 | #include <bits/stdc++.h> using namespace std; const int MOD = 1000000007; struct Node { int ch[2]; int size; int cost[2]; }; typedef vector<Node> Tree; void prepareTree(Tree &D, int root) { if (!root) return; int l=D[root].ch[0]; int r=D[root].ch[1]; prepareTree(D, l); prepareTree(D, r); D[root].size=D[l].size+D[r].size+1; D[root].cost[0] = (0LL+ D[l].cost[0] + D[r].cost[1] + D[r].size)%MOD; D[root].cost[1] = (0LL+ D[l].cost[0] + D[r].cost[1] + D[l].size)%MOD; } int bzium(const Tree &D1, int root1, const Tree &D2, int root2) { if (root1==0) return 0; int res=0; (res+=abs(root1-root2))%=MOD; int l1=D1[root1].ch[0]; int r1=D1[root1].ch[1]; int l2=D2[root2].ch[0]; int r2=D2[root2].ch[1]; while (D1[l1].size != D2[l2].size) { if (D1[l1].size > D2[l2].size) { (res+= (D1[ D1[l1].ch[1] ].size + D1[ D1[l1].ch[1] ].cost[1])%MOD )%=MOD; l1=D1[l1].ch[0]; } else { (res+= (D2[ D2[l2].ch[1] ].size + D2[ D2[l2].ch[1] ].cost[1])%MOD )%=MOD; l2=D2[l2].ch[0]; } } while (D1[r1].size != D2[r2].size) { if (D1[r1].size > D2[r2].size) { (res+= (D1[ D1[r1].ch[0] ].size + D1[ D1[r1].ch[0] ].cost[0])%MOD )%=MOD; r1=D1[r1].ch[1]; } else { (res+= (D2[ D2[r2].ch[0] ].size + D2[ D2[r2].ch[0] ].cost[0])%MOD )%=MOD; r2=D2[r2].ch[1]; } } (res+=bzium(D1, l1, D2, l2))%=MOD; (res+=bzium(D1, r1, D2, r2))%=MOD; return res; } int main() { ios::sync_with_stdio(0); cin.tie(0); int n; cin >> n; Tree D1(n+1, {0, 0, 0, 0, 0}); int root1; Tree D2(n+1, {0, 0, 0, 0, 0}); int root2; for (int i=1; i<=n; i++) { int x; cin >> x; ((x==-1)?root1:D1[x].ch[x<i])=i; } for (int i=1; i<=n; i++) { int x; cin >> x; ((x==-1)?root2:D2[x].ch[x<i])=i; } prepareTree(D1, root1); // for (int i=1; i<=n; i++) cout << i << " " << D1[i].size << " " << D1[i].cost[0] << " " << D1[i].cost[1] << endl; prepareTree(D2, root2); cout << bzium(D1, root1, D2, root2) << endl; return 0; } |