#include <iostream> #include <tuple> const int MAXN = 500005; const int MOD = 1000000007; struct Node { Node() : l(-1), r(-1) {} int l, r; } A[MAXN], B[MAXN]; int n; // int Min(int root, Node* tree) { // if (root == -1) return root; // else if (tree[root].l == -1) return root; // else return Min(tree[root].l, tree); // } // int Max(int root, Node* tree) { // if (root == -1) return root; // else if (tree[root].r == -1) return root; // else return Max(tree[root].r, tree); // } std::pair<int, int> L(int root, Node* tree); std::pair<int, int> R(int root, Node* tree); std::pair<int, int> L(int root, Node* tree) { if (root == -1) return {0, 0}; int lv,lc,rv,rc; std::tie(lv, lc) = L(tree[root].l, tree); std::tie(rv, rc) = R(tree[root].r, tree); return {((lv+rv)%MOD+rc)%MOD, lc+rc+1}; } std::pair<int, int> R(int root, Node* tree) { if (root == -1) return {0, 0}; int lv,lc,rv,rc; std::tie(lv, lc) = L(tree[root].l, tree); std::tie(rv, rc) = R(tree[root].r, tree); return {((lv+rv)%MOD+lc)%MOD, lc+rc+1}; } int iL(int root, Node* tree) { if (root == -1) return 0; int v,c; std::tie(v, c) = R(tree[root].r, tree); return (v+c)%MOD; } int iR(int root, Node* tree) { if (root == -1) return 0; int v,c; std::tie(v, c) = L(tree[root].l, tree); return (v+c)%MOD; } std::tuple<int, int, int> iL(int root, int target, Node* tree) { if (root <= target) { return {iL(root, tree), tree[root].l, root}; } else { int c,m,mm; std::tie(c, m, mm) = iL(tree[root].l, target, tree); return { (c + iL(root, tree))%MOD, m, mm}; } } std::tuple<int, int, int> iR(int root, int target, Node* tree) { // std::clog << "iR " << root << " -> " << target << std::endl; if (root >= target) { return {iR(root, tree), tree[root].r, root}; } else { int c,m,mm; std::tie(c, m, mm) = iR(tree[root].r, target, tree); return { (c + iR(root, tree))%MOD, m, mm}; } } void debugTree(int root, Node* tree) { if (root == -1) return; std::clog << " :: " << root << " -> " << tree[root].l << ", " << tree[root].r << std::endl; debugTree(tree[root].l, tree); debugTree(tree[root].r, tree); } int solve(int a, int b, Node* ta, Node* tb) { if (a == -1 || b == -1) return 0; if (a < b) return solve(b, a, tb, ta); if (a == b) return (solve(ta[a].l, tb[b].l, ta, tb)+solve(ta[a].r, tb[b].r, ta, tb))%MOD; int cost = a - b; int ac,amr,am, bc, bmr, bm; std::tie(ac, amr, am) = iL(ta[a].l, b, ta); std::tie(bc, bmr, bm) = iR(tb[b].r, a, tb); cost = (cost + ac)%MOD; cost = (cost + bc)%MOD; int alr = amr, arr = ta[a].r; int blr = tb[b].l, brr = bmr; int alv = am; int arv = a;//Max(ta[a].l, ta); int blv = b;//Min(tb[b].r, tb); int brv = bm; while (alv != blv || arv != brv) { if (alv < blv) { int cc,nr,nv; std::tie(cc, nr, nv) = iL(blr, alv, tb); cost = (cost + cc)%MOD; blr = nr; blv = nv; } else if (alv > blv) { int cc,nr,nv; std::tie(cc, nr, nv) = iL(alr, blv, ta); cost = (cost + cc)%MOD; alr = nr; alv = nv; } if (arv < brv) { int cc,nr,nv; std::tie(cc, nr, nv) = iR(arr, brv, ta); cost = (cost + cc)%MOD; arr = nr; arv = nv; } else if (arv > brv) { int cc,nr,nv; std::tie(cc, nr, nv) = iR(brr, arv, tb); cost = (cost + cc)%MOD; brr = nr; brv = nv; } } cost = (cost + solve(alr, blr, ta, tb))%MOD; cost = (cost + solve(arr, brr, ta, tb))%MOD; return cost; } int main() { std::ios_base::sync_with_stdio(0); std::cin >> n; int a,b; for (int i=1;i<=n;++i) { int p; std::cin >> p; if (p == -1) { a = i; continue; } if (i < p) A[p].l = i; else A[p].r = i; } for (int i=1;i<=n;++i) { int p; std::cin >> p; if (p == -1) { b = i; continue; } if (i < p) B[p].l = i; else B[p].r = i; } std::cout << solve(a, b, A, B) << std::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 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 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | #include <iostream> #include <tuple> const int MAXN = 500005; const int MOD = 1000000007; struct Node { Node() : l(-1), r(-1) {} int l, r; } A[MAXN], B[MAXN]; int n; // int Min(int root, Node* tree) { // if (root == -1) return root; // else if (tree[root].l == -1) return root; // else return Min(tree[root].l, tree); // } // int Max(int root, Node* tree) { // if (root == -1) return root; // else if (tree[root].r == -1) return root; // else return Max(tree[root].r, tree); // } std::pair<int, int> L(int root, Node* tree); std::pair<int, int> R(int root, Node* tree); std::pair<int, int> L(int root, Node* tree) { if (root == -1) return {0, 0}; int lv,lc,rv,rc; std::tie(lv, lc) = L(tree[root].l, tree); std::tie(rv, rc) = R(tree[root].r, tree); return {((lv+rv)%MOD+rc)%MOD, lc+rc+1}; } std::pair<int, int> R(int root, Node* tree) { if (root == -1) return {0, 0}; int lv,lc,rv,rc; std::tie(lv, lc) = L(tree[root].l, tree); std::tie(rv, rc) = R(tree[root].r, tree); return {((lv+rv)%MOD+lc)%MOD, lc+rc+1}; } int iL(int root, Node* tree) { if (root == -1) return 0; int v,c; std::tie(v, c) = R(tree[root].r, tree); return (v+c)%MOD; } int iR(int root, Node* tree) { if (root == -1) return 0; int v,c; std::tie(v, c) = L(tree[root].l, tree); return (v+c)%MOD; } std::tuple<int, int, int> iL(int root, int target, Node* tree) { if (root <= target) { return {iL(root, tree), tree[root].l, root}; } else { int c,m,mm; std::tie(c, m, mm) = iL(tree[root].l, target, tree); return { (c + iL(root, tree))%MOD, m, mm}; } } std::tuple<int, int, int> iR(int root, int target, Node* tree) { // std::clog << "iR " << root << " -> " << target << std::endl; if (root >= target) { return {iR(root, tree), tree[root].r, root}; } else { int c,m,mm; std::tie(c, m, mm) = iR(tree[root].r, target, tree); return { (c + iR(root, tree))%MOD, m, mm}; } } void debugTree(int root, Node* tree) { if (root == -1) return; std::clog << " :: " << root << " -> " << tree[root].l << ", " << tree[root].r << std::endl; debugTree(tree[root].l, tree); debugTree(tree[root].r, tree); } int solve(int a, int b, Node* ta, Node* tb) { if (a == -1 || b == -1) return 0; if (a < b) return solve(b, a, tb, ta); if (a == b) return (solve(ta[a].l, tb[b].l, ta, tb)+solve(ta[a].r, tb[b].r, ta, tb))%MOD; int cost = a - b; int ac,amr,am, bc, bmr, bm; std::tie(ac, amr, am) = iL(ta[a].l, b, ta); std::tie(bc, bmr, bm) = iR(tb[b].r, a, tb); cost = (cost + ac)%MOD; cost = (cost + bc)%MOD; int alr = amr, arr = ta[a].r; int blr = tb[b].l, brr = bmr; int alv = am; int arv = a;//Max(ta[a].l, ta); int blv = b;//Min(tb[b].r, tb); int brv = bm; while (alv != blv || arv != brv) { if (alv < blv) { int cc,nr,nv; std::tie(cc, nr, nv) = iL(blr, alv, tb); cost = (cost + cc)%MOD; blr = nr; blv = nv; } else if (alv > blv) { int cc,nr,nv; std::tie(cc, nr, nv) = iL(alr, blv, ta); cost = (cost + cc)%MOD; alr = nr; alv = nv; } if (arv < brv) { int cc,nr,nv; std::tie(cc, nr, nv) = iR(arr, brv, ta); cost = (cost + cc)%MOD; arr = nr; arv = nv; } else if (arv > brv) { int cc,nr,nv; std::tie(cc, nr, nv) = iR(brr, arv, tb); cost = (cost + cc)%MOD; brr = nr; brv = nv; } } cost = (cost + solve(alr, blr, ta, tb))%MOD; cost = (cost + solve(arr, brr, ta, tb))%MOD; return cost; } int main() { std::ios_base::sync_with_stdio(0); std::cin >> n; int a,b; for (int i=1;i<=n;++i) { int p; std::cin >> p; if (p == -1) { a = i; continue; } if (i < p) A[p].l = i; else A[p].r = i; } for (int i=1;i<=n;++i) { int p; std::cin >> p; if (p == -1) { b = i; continue; } if (i < p) B[p].l = i; else B[p].r = i; } std::cout << solve(a, b, A, B) << std::endl; return 0; } |