結果
問題 |
No.1698 Face to Face
|
ユーザー |
|
提出日時 | 2025-05-24 16:10:29 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 557 ms / 5,000 ms |
コード長 | 10,843 bytes |
コンパイル時間 | 2,517 ms |
コンパイル使用メモリ | 211,624 KB |
実行使用メモリ | 222,072 KB |
最終ジャッジ日時 | 2025-05-24 16:10:47 |
合計ジャッジ時間 | 16,134 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 45 |
ソースコード
#include <bits/stdc++.h> #define pb emplace_back #define fst first #define scd second #define mkp make_pair #define mems(a, x) memset((a), (x), sizeof(a)) using namespace std; typedef long long ll; typedef double db; typedef unsigned long long ull; typedef long double ldb; typedef pair<int, int> pii; namespace IO { const int maxn = 1 << 20; char ibuf[maxn], *iS, *iT, obuf[maxn], *oS = obuf; inline char gc() { return (iS == iT ? iT = (iS = ibuf) + fread(ibuf, 1, maxn, stdin), (iS == iT ? EOF : *iS++) : *iS++); } template<typename T = int> inline T read() { char c = gc(); T x = 0; bool f = 0; while (c < '0' || c > '9') { f |= (c == '-'); c = gc(); } while (c >= '0' && c <= '9') { x = (x << 1) + (x << 3) + (c ^ 48); c = gc(); } return f ? ~(x - 1) : x; } inline int reads(char *s) { char c = gc(); int len = 0; while (isspace(c)) { c = gc(); } while (!isspace(c)) { s[len++] = c; c = gc(); } return len; } inline void flush() { fwrite(obuf, 1, oS - obuf, stdout); oS = obuf; } struct Flusher { ~Flusher() { flush(); } } AutoFlush; inline void pc(char ch) { if (oS == obuf + maxn) { flush(); } *oS++ = ch; } template<typename T> inline void write(T x) { static char stk[64], *tp = stk; if (x < 0) { x = ~(x - 1); pc('-'); } do { *tp++ = x % 10; x /= 10; } while (x); while (tp != stk) { pc((*--tp) | 48); } } template<typename T> inline void writesp(T x) { write(x); pc(' '); } template<typename T> inline void writeln(T x) { write(x); pc('\n'); } } using IO::read; using IO::reads; using IO::write; using IO::pc; using IO::writesp; using IO::writeln; const int maxn = 100100; const int logn = 20; int n, a[maxn], b[maxn], p[maxn], lsa[maxn], rsa[maxn], lsb[maxn], rsb[maxn], ib[maxn], c[maxn], ia[maxn], ip[maxn], ic[maxn]; int stk[maxn], top, ans[maxn]; int la[maxn], ra[maxn], lb[maxn], rb[maxn], st1[maxn], ed1[maxn], st2[maxn], ed2[maxn], tim, fa[logn][maxn], fb[logn][maxn]; pii f1[logn][maxn], f2[logn][maxn]; inline pii qmax(pii f[logn][maxn], int l, int r) { int k = __lg(r - l + 1); return max(f[k][l], f[k][r - (1 << k) + 1]); } void dfs(int u) { st1[u] = ++tim; la[u] = ra[u] = u; if (lsa[u]) { dfs(lsa[u]); la[u] = la[lsa[u]]; } if (rsa[u]) { dfs(rsa[u]); ra[u] = ra[rsa[u]]; } ed1[u] = tim; } void dfs2(int u) { st2[u] = ++tim; lb[u] = rb[u] = u; if (lsb[u]) { dfs2(lsb[u]); lb[u] = lb[lsb[u]]; } if (rsb[u]) { dfs2(rsb[u]); rb[u] = rb[rsb[u]]; } ed2[u] = tim; } int rt[maxn], ls[maxn * 20], rs[maxn * 20], val[maxn * 20], nt; int build(int l, int r) { int rt = ++nt; if (l == r) { return rt; } int mid = (l + r) >> 1; ls[rt] = build(l, mid); rs[rt] = build(mid + 1, r); return rt; } int update(int rt, int l, int r, int x) { int u = ++nt; ls[u] = ls[rt]; rs[u] = rs[rt]; val[u] = val[rt] + 1; if (l == r) { return u; } int mid = (l + r) >> 1; if (x <= mid) { ls[u] = update(ls[u], l, mid, x); } else { rs[u] = update(rs[u], mid + 1, r, x); } return u; } int query(int u, int v, int l, int r, int ql, int qr) { if (ql <= l && r <= qr) { return val[v] - val[u]; } int mid = (l + r) >> 1, res = 0; if (ql <= mid) { res += query(ls[u], ls[v], l, mid, ql, qr); } if (qr > mid) { res += query(rs[u], rs[v], mid + 1, r, ql, qr); } return res; } inline int calc(int u, int v) { return query(rt[st1[u] - 1], rt[ed1[u]], 1, n, st2[v], ed2[v]); } inline void upd(int l, int r, int x) { if (l > r) { return; } ans[l] += x; ans[r + 1] -= x; } struct DSU { int fa[maxn]; bool vis[maxn]; int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); } inline void init() { for (int i = 1; i <= n; ++i) { fa[i] = i; } } } D1, D2; inline void upd1(int u, int k, int o) { int x = la[u]; int y = D2.find(x); if (D2.vis[y] && lb[y] < la[u] && rb[y] < ra[u]) { ans[k] += min(rb[y] - la[u] + 1, calc(u, y)) * o; } x = ra[u]; y = D2.find(x); if (D2.vis[y] && la[u] < lb[y] && ra[u] < rb[y]) { ans[k] += min(ra[u] - lb[y] + 1, calc(u, y)) * o; } } inline void upd2(int u, int k, int o) { int x = lb[u]; int y = D1.find(x); if (D1.vis[y] && la[y] < lb[u] && ra[y] < rb[u]) { ans[k] += min(ra[y] - lb[u] + 1, calc(y, u)) * o; } x = rb[u]; y = D1.find(x); if (D1.vis[y] && lb[u] < la[y] && rb[u] < ra[y]) { ans[k] += min(rb[u] - la[y] + 1, calc(y, u)) * o; } } namespace SGT { int sa[maxn << 6], sb[maxn << 6], sab[maxn << 6], ls[maxn << 6], rs[maxn << 6], nt; inline void init() { mems(sa, 0); mems(sb, 0); mems(sab, 0); mems(ls, 0); mems(rs, 0); nt = 0; } inline void pushup(int x) { sa[x] = sa[ls[x]] + sa[rs[x]]; sb[x] = sb[ls[x]] + sb[rs[x]]; sab[x] = sab[ls[x]] + sab[rs[x]] + sa[ls[x]] * sb[rs[x]]; } void update1(int &rt, int l, int r, int x, int y) { if (!rt) { rt = ++nt; } if (l == r) { sa[rt] += y; sab[rt] += sb[rt] * y; return; } int mid = (l + r) >> 1; (x <= mid) ? update1(ls[rt], l, mid, x, y) : update1(rs[rt], mid + 1, r, x, y); pushup(rt); } void update2(int &rt, int l, int r, int x, int y) { if (!rt) { rt = ++nt; } if (l == r) { sb[rt] += y; sab[rt] += sa[rt] * y; return; } int mid = (l + r) >> 1; (x <= mid) ? update2(ls[rt], l, mid, x, y) : update2(rs[rt], mid + 1, r, x, y); pushup(rt); } int merge(int u, int v, int l, int r) { if (!u || !v) { return u | v; } if (l == r) { sa[u] += sa[v]; sb[u] += sb[v]; sab[u] = sa[u] * sb[u]; return u; } int mid = (l + r) >> 1; ls[u] = merge(ls[u], ls[v], l, mid); rs[u] = merge(rs[u], rs[v], mid + 1, r); pushup(u); return u; } } vector<pii> md[maxn]; int tr[maxn]; void dfs3(int u) { for (int v : {lsb[u], rsb[u]}) { if (!v) { continue; } dfs3(v); tr[u] = SGT::merge(tr[u], tr[v], 1, n); } SGT::update2(tr[u], 1, n, ic[st2[u]], 1); for (pii p : md[u]) { SGT::update1(tr[u], 1, n, st1[p.fst], p.scd); if (ed1[p.fst] < n) { SGT::update1(tr[u], 1, n, ed1[p.fst] + 1, -p.scd); } } upd(b[u], b[fb[0][u]] - 1, SGT::sab[tr[u]]); } void dfs4(int u) { for (int v : {lsa[u], rsa[u]}) { if (!v) { continue; } dfs4(v); tr[u] = SGT::merge(tr[u], tr[v], 1, n); } SGT::update2(tr[u], 1, n, c[st1[u]], 1); for (pii p : md[u]) { SGT::update1(tr[u], 1, n, st2[p.fst], p.scd); if (ed2[p.fst] < n) { SGT::update1(tr[u], 1, n, ed2[p.fst] + 1, -p.scd); } } upd(a[u], a[fa[0][u]] - 1, SGT::sab[tr[u]]); } void solve() { n = read(); for (int i = 1; i <= n; ++i) { a[i] = read(); ia[a[i]] = i; } for (int i = 1; i <= n; ++i) { b[i] = read(); ib[b[i]] = i; } a[0] = b[0] = n + 1; for (int i = 1; i <= n; ++i) { int k = top; while (k && a[stk[k]] < a[i]) { --k; } if (k) { rsa[stk[k]] = i; } if (k < top) { lsa[i] = stk[k + 1]; } stk[top = (++k)] = i; } int rt1 = stk[1]; top = 0; for (int i = 1; i <= n; ++i) { int k = top; while (k && b[stk[k]] < b[i]) { --k; } if (k) { rsb[stk[k]] = i; } if (k < top) { lsb[i] = stk[k + 1]; } stk[top = (++k)] = i; } int rt2 = stk[1]; tim = 0; dfs(rt1); tim = 0; dfs2(rt2); for (int i = 1; i <= n; ++i) { p[i] = read(); ip[p[i]] = i; } for (int i = 1; i <= n; ++i) { f1[0][i] = mkp(a[i], i); f2[0][i] = mkp(b[i], i); } for (int j = 1; (1 << j) <= n; ++j) { for (int i = 1; i + (1 << j) - 1 <= n; ++i) { f1[j][i] = max(f1[j - 1][i], f1[j - 1][i + (1 << (j - 1))]); f2[j][i] = max(f2[j - 1][i], f2[j - 1][i + (1 << (j - 1))]); } } for (int i = 1; i <= n; ++i) { c[st1[i]] = st2[ib[p[a[i]]]]; } for (int i = 1; i <= n; ++i) { ic[c[i]] = i; } rt[0] = build(1, n); for (int i = 1; i <= n; ++i) { rt[i] = update(rt[i - 1], 1, n, c[i]); } for (int i = 1; i <= n; ++i) { if (lsa[i]) { fa[0][lsa[i]] = i; } if (rsa[i]) { fa[0][rsa[i]] = i; } if (lsb[i]) { fb[0][lsb[i]] = i; } if (rsb[i]) { fb[0][rsb[i]] = i; } } for (int j = 1; j <= 18; ++j) { for (int i = 1; i <= n; ++i) { fa[j][i] = fa[j - 1][fa[j - 1][i]]; fb[j][i] = fb[j - 1][fb[j - 1][i]]; } } D1.init(); D2.init(); for (int k = 1; k <= n; ++k) { int u = ia[k]; if (lsa[u]) { upd1(lsa[u], k, -1); D1.fa[lsa[u]] = u; } if (rsa[u]) { upd1(rsa[u], k, -1); D1.fa[rsa[u]] = u; } upd1(u, k, 1); D1.vis[u] = 1; u = ib[k]; if (lsb[u]) { upd2(lsb[u], k, -1); D2.fa[lsb[u]] = u; } if (rsb[u]) { upd2(rsb[u], k, -1); D2.fa[rsb[u]] = u; } upd2(u, k, 1); D2.vis[u] = 1; } for (int i = 1; i <= n; ++i) { if (p[a[i]] == b[i]) { upd(1, min(a[i], b[i]) - 1, 1); } int u = i; for (int j = 18; ~j; --j) { if (fb[j][u]) { int v = fb[j][u]; if (!(st2[v] <= st2[ib[p[a[i]]]] && st2[ib[p[a[i]]]] <= ed2[v])) { u = v; } } } if (!(st2[u] <= st2[ib[p[a[i]]]] && st2[ib[p[a[i]]]] <= ed2[u])) { u = fb[0][u]; } upd(b[u], a[i] - 1, 1); u = i; for (int j = 18; ~j; --j) { if (fa[j][u]) { int v = fa[j][u]; if (!(st1[v] <= st1[ia[ip[b[i]]]] && st1[ia[ip[b[i]]]] <= ed1[v])) { u = v; } } } if (!(st1[u] <= st1[ia[ip[b[i]]]] && st1[ia[ip[b[i]]]] <= ed1[u])) { u = fa[0][u]; } upd(a[u], b[i] - 1, 1); } for (int u = 1; u <= n; ++u) { int v = qmax(f2, la[u], ra[u]).scd; if (b[v] < a[u]) { for (int j = 18; ~j; --j) { if (fb[j][v] && b[fb[j][v]] < a[u]) { v = fb[j][v]; } } upd(max(a[u], b[v]), min(a[fa[0][u]], b[fb[0][v]]) - 1, calc(u, v)); v = fb[0][v]; } if (b[v] <= a[fa[0][u]] - 1) { int w = v; for (int j = 18; ~j; --j) { if (fb[j][w] && b[fb[j][w]] <= a[fa[0][u]] - 1) { w = fb[j][w]; } } upd(max(a[u], b[w]), min(a[fa[0][u]], b[fb[0][w]]) - 1, calc(u, w)); if (w != v) { md[v].pb(u, 1); md[w].pb(u, -1); } } } dfs3(rt2); mems(tr, 0); for (int i = 1; i <= n; ++i) { vector<pii>().swap(md[i]); } for (int u = 1; u <= n; ++u) { int v = qmax(f1, lb[u], rb[u]).scd; if (lb[u] == la[v] && ra[v] == rb[u]) { upd(max(a[v], b[u]), min(a[fa[0][v]], b[fb[0][u]]) - 1, -calc(v, u)); } if (a[v] < b[u]) { for (int j = 18; ~j; --j) { if (fa[j][v] && a[fa[j][v]] < b[u]) { v = fa[j][v]; } } upd(max(a[v], b[u]), min(a[fa[0][v]], b[fb[0][u]]) - 1, calc(v, u)); v = fa[0][v]; } if (a[v] <= b[fb[0][u]] - 1) { int w = v; for (int j = 18; ~j; --j) { if (fa[j][w] && a[fa[j][w]] <= b[fb[0][u]] - 1) { w = fa[j][w]; } } upd(max(a[w], b[u]), min(a[fa[0][w]], b[fb[0][u]]) - 1, calc(w, u)); if (w != v) { md[v].pb(u, 1); md[w].pb(u, -1); } } } SGT::init(); dfs4(rt1); for (int i = 1; i <= n; ++i) { ans[i] += ans[i - 1]; writeln(ans[i]); } } int main() { int T = 1; // scanf("%d", &T); while (T--) { solve(); } return 0; }