首页 > 代码库 > bzoj4430 [Nwerc2015]Guessing Camels赌骆驼

bzoj4430 [Nwerc2015]Guessing Camels赌骆驼

传送门: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;
}
View Code

 

bzoj4430 [Nwerc2015]Guessing Camels赌骆驼