传送门
每个人有3个属性,如果有人的3个属性都比自己大,那么自己就会跳楼。
求跳楼的人的个数。
以前CDQ一般是求属性小于等于自己的个数,现在变成求有没有人的属性比自己大。
你没有办法直接求出比自己小的人有哪些的,因为用的是树状数组维护个数。
那么转换下就是对于每一个人求大于自己的人的个数,把所有的权值变成负数,那么就转换回CDQ套路了。
但是还有个问题就是第一个属性排序,第二个属性归并排序,第三个属性树状数组。
第二维和第三维都是可以控制找到小于自己的个数,如果说第一个维度相同,另外两个维度满足,也会算进答案了。
所以有一个方法就是,对于每一个第一维度相同的,再进行一次CDQ,把多于的值减去即可。分段求下CDQ
时间复杂度(O(nlog^2n))
老规矩,树状数组维护的那一维度要离散化。
#include <bits/stdc++.h>
#define ll long long
#define CASE int Kase = 0; cin >> Kase; for(int kase = 1; kase <= Kase; kase++)
using namespace std;
template<typename T = long long> inline T read() {
T s = 0, f = 1; char ch = getchar();
while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
while(isdigit(ch)) {s = (s << 3) + (s << 1) + ch - 48; ch = getchar();}
return s * f;
}
const int N = 5e5 + 5, M = 1e6 + 5, MOD = 1e9 + 7, CM = 998244353, INF = 0x3f3f3f3f;
struct Lady{
int beauty, intellect, richness, id;
bool operator < (const Lady &b) const {
if(beauty == b.beauty && intellect == b.intellect) return richness < b.richness;
return beauty ^ b.beauty ? beauty < b.beauty : intellect < b.intellect;
}
} lady[N], tmp[N];
struct BIT{
int c[N];
int lowbit(int x) {return x & (-x);}
void add(int pos, int val) {for(; pos < N; pos += lowbit(pos)) c[pos] += val;}
int sum(int pos) { int res = 0; for(; pos; pos -= lowbit(pos)) res += c[pos]; return res;}
} bit;
int b[N], ans[N];
void CDQ(int l, int r, int op){
if(l == r) return;
int mid = (l + r) >> 1;
CDQ(l, mid, op), CDQ(mid + 1, r, op);
int lp = l, rp = mid + 1, pos = l;
while(lp <= mid && rp <= r) {
if(lady[lp].intellect < lady[rp].intellect) bit.add(lady[lp].richness, 1), tmp[pos++] = lady[lp++];
else ans[lady[rp].id] += op * bit.sum(lady[rp].richness - 1), tmp[pos++] = lady[rp++];
}
while(lp <= mid) bit.add(lady[lp].richness, 1), tmp[pos++] = lady[lp++];
while(rp <= r) ans[lady[rp].id] += op * bit.sum(lady[rp].richness - 1), tmp[pos++] = lady[rp++];
for(int i = l; i <= mid; i++) bit.add(lady[i].richness, -1);
for(int i = l; i <= r; i++) lady[i] = tmp[i];
}
int main(){
int n = read();
for(int i = 1; i <= n; i++) lady[i].beauty = -read();
for(int i = 1; i <= n; i++) lady[i].intellect = -read();
for(int i = 1; i <= n; i++) lady[i].richness = -read(), lady[i].id = i, b[i] = lady[i].richness;
sort(b + 1, b + n + 1);
int q = unique(b + 1, b + n + 1) - b - 1;
for(int i = 1; i <= n; i++) {
lady[i].richness = lower_bound(b + 1, b + q + 1, lady[i].richness) - b;
}
sort(lady + 1, lady + n + 1);
CDQ(1, n, 1);
sort(lady + 1, lady + n + 1);
for(int i = 1; i <= n; i++) {
int j = i + 1;
for(; j <= n; j++) if(lady[i].beauty != lady[j].beauty) break;
CDQ(i, j - 1, -1);
i = j - 1;
}
int res = 0;
for(int i = 1; i <= n; i++) {
res += ans[i] ? 1 : 0;
}
printf("%d
", res);
return 0;
}