传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4430
【题解】
把每只骆驼在第一个人、第二个人、第三个人的位置找出来,然后做三维偏序即可。
排序+cdq分治+BIT
# include <stdio.h> # include <string.h> # include <iostream> # include <algorithm> // # include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; const int M = 2e5 + 10; const int mod = 1e9+7; # define RG register # define ST static int n, a[M], b[M], c[M], pb[M], pc[M]; ll ans = 0; struct pa { int a, b, c, ans; pa() {} pa(int a, int b, int c, int ans) : a(a), b(b), c(c), ans(ans) {} friend bool operator <(pa a, pa b) { return a.b < b.b || (a.b == b.b && a.a < b.a) || (a.b == b.b && a.a == b.a && a.c < b.c); } }p[M], t[M]; struct BIT { int n, c[M]; # define lb(x) (x&(-x)) inline void set(int _n) { n = _n; memset(c, 0, sizeof c); } inline void edt(int x, int d) { for (; x<=n; x+=lb(x)) c[x] += d; } inline int sum(int x) { int ret = 0; for (; x; x-=lb(x)) ret += c[x]; return ret; } inline int sum(int x, int y) { if(x > y) return 0; return sum(y) - sum(x-1); } }T; inline void solve(int l, int r) { if(l == r) return; int mid = l+r>>1, t1n = l-1, t2n = mid; for (int i=l; i<=r; ++i) if(p[i].a <= mid) t[++t1n] = p[i]; else t[++t2n] = p[i]; for (int i=l; i<=r; ++i) p[i] = t[i]; int j=l; for (int i=mid+1; i<=r; ++i) { while(j<=mid && p[j].b <= p[i].b) T.edt(p[j].c, 1), j++; p[i].ans += T.sum(p[i].c); } for (int i=l; i<j; ++i) T.edt(p[i].c, -1); solve(l, mid); solve(mid+1, r); } int main() { cin >> n; T.set(n); for (int i=1; i<=n; ++i) scanf("%d", a+i); for (int i=1; i<=n; ++i) scanf("%d", b+i), pb[b[i]] = i; for (int i=1; i<=n; ++i) scanf("%d", c+i), pc[c[i]] = i; for (int i=1; i<=n; ++i) p[i] = pa(i, pb[a[i]], pc[a[i]], 0); // for (int i=1; i<=n; ++i) printf("%d %d %d\n", p[i].a, p[i].b, p[i].c); sort(p+1, p+n+1); solve(1, n); for (int i=1; i<=n; ++i) ans += p[i].ans; cout << ans; return 0; }
时间: 2024-10-12 21:03:12