#include <bits/stdc++.h> using namespace std; #define REP(i,a,b) for (int i = (a); i <= (b); ++i) #define REPD(i,a,b) for (int i = (a); i >= (b); --i) #define FORI(i,n) REP(i,1,n) #define FOR(i,n) REP(i,0,int(n)-1) #define mp make_pair #define pb push_back #define pii pair<int,int> #define vi vector<int> #define ll long long #define SZ(x) int((x).size()) #define DBG(v) cerr << #v << " = " << (v) << endl; #define FOREACH(i,t) for (typeof(t.begin()) i=t.begin(); i!=t.end(); i++) #define fi first #define se second const int N = 500500; int n; int a[2][N]; ll res; int gl[2][N], gr[2][N]; int flatten(int k, int u) { int sl = 0, sr = 0; if (gl[k][u]) sl = flatten(k, gl[k][u]); if (gr[k][u]) sr = flatten(k, gr[k][u]); if (a[k][u]>u) res += sr; else res += sl; return sl+sr+1; } void make_path(int k, int le, int ri, int root0, int root1) { int par = a[k][root0]; if (par < root0) { if (gl[k][root0]) { res += flatten(k, gl[k][root0]); REP(i,par,root0) { if (i!=par) { a[k][i] = i-1; gl[k][i] = 0; } if (i!=root0) { gr[k][i] = i+1; } } } if (root0 < root1) { make_path(k, root0+1, ri, gr[k][root0], root1); } } else { if (gr[k][root0]) { res += flatten(k, gr[k][root0]); REP(i,root0,par) { if (i!=root0) { gl[k][i] = i-1; } if (i!=par) { a[k][i] = i+1; gr[k][i] = 0; } } } if (root0 > root1) { make_path(k, le, root0-1, gl[k][root0], root1); } } } void rec(int k, int le, int ri, int root0, int root1) { if (root0 == root1) { if (gl[k][root0] != 0) rec(k, le, root0-1, gl[k][root0], gl[!k][root1]); if (gr[k][root0] != 0) rec(k, root0+1, ri, gr[k][root0], gr[!k][root1]); } else if (root0 < root1) { make_path(k, root0+1, ri, gr[k][root0], root1); make_path(!k, le, root1-1, gl[!k][root1], root0); rec(k, root1+1, ri, gr[k][root1], gr[!k][root1]); rec(!k, le, root0-1, gl[!k][root0], gl[k][root0]); res += root1 - root0; } else { rec(!k, le, ri, root1, root0); } } int main() { scanf("%d", &n); FORI(i,n) scanf("%d", &a[0][i]); FORI(i,n) scanf("%d", &a[1][i]); int root[2]; FOR(k,2) FORI(i,n) { if (a[k][i] != -1) { if (a[k][i] < i) gr[k][a[k][i]] = i; else gl[k][a[k][i]] = i; } else { root[k] = i; } } rec(0, 1, n, root[0], root[1]); printf("%lld\n", res%1000000007); 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 | #include <bits/stdc++.h> using namespace std; #define REP(i,a,b) for (int i = (a); i <= (b); ++i) #define REPD(i,a,b) for (int i = (a); i >= (b); --i) #define FORI(i,n) REP(i,1,n) #define FOR(i,n) REP(i,0,int(n)-1) #define mp make_pair #define pb push_back #define pii pair<int,int> #define vi vector<int> #define ll long long #define SZ(x) int((x).size()) #define DBG(v) cerr << #v << " = " << (v) << endl; #define FOREACH(i,t) for (typeof(t.begin()) i=t.begin(); i!=t.end(); i++) #define fi first #define se second const int N = 500500; int n; int a[2][N]; ll res; int gl[2][N], gr[2][N]; int flatten(int k, int u) { int sl = 0, sr = 0; if (gl[k][u]) sl = flatten(k, gl[k][u]); if (gr[k][u]) sr = flatten(k, gr[k][u]); if (a[k][u]>u) res += sr; else res += sl; return sl+sr+1; } void make_path(int k, int le, int ri, int root0, int root1) { int par = a[k][root0]; if (par < root0) { if (gl[k][root0]) { res += flatten(k, gl[k][root0]); REP(i,par,root0) { if (i!=par) { a[k][i] = i-1; gl[k][i] = 0; } if (i!=root0) { gr[k][i] = i+1; } } } if (root0 < root1) { make_path(k, root0+1, ri, gr[k][root0], root1); } } else { if (gr[k][root0]) { res += flatten(k, gr[k][root0]); REP(i,root0,par) { if (i!=root0) { gl[k][i] = i-1; } if (i!=par) { a[k][i] = i+1; gr[k][i] = 0; } } } if (root0 > root1) { make_path(k, le, root0-1, gl[k][root0], root1); } } } void rec(int k, int le, int ri, int root0, int root1) { if (root0 == root1) { if (gl[k][root0] != 0) rec(k, le, root0-1, gl[k][root0], gl[!k][root1]); if (gr[k][root0] != 0) rec(k, root0+1, ri, gr[k][root0], gr[!k][root1]); } else if (root0 < root1) { make_path(k, root0+1, ri, gr[k][root0], root1); make_path(!k, le, root1-1, gl[!k][root1], root0); rec(k, root1+1, ri, gr[k][root1], gr[!k][root1]); rec(!k, le, root0-1, gl[!k][root0], gl[k][root0]); res += root1 - root0; } else { rec(!k, le, ri, root1, root0); } } int main() { scanf("%d", &n); FORI(i,n) scanf("%d", &a[0][i]); FORI(i,n) scanf("%d", &a[1][i]); int root[2]; FOR(k,2) FORI(i,n) { if (a[k][i] != -1) { if (a[k][i] < i) gr[k][a[k][i]] = i; else gl[k][a[k][i]] = i; } else { root[k] = i; } } rec(0, 1, n, root[0], root[1]); printf("%lld\n", res%1000000007); return 0; } |