题目链接:Contest
正面去想:只需要枚举3种情况即可。
反面去想:总方案-不贡献答案的对数。
我采用的反面的做法,不贡献答案的对数就是三维偏序的对数。简单cdq分治即可。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=2e5+10;
int n,d[N]; long long res;
struct node{int a,b,c;}t[N];
int cmpa(node s1,node s2){return s1.a<s2.a;}
int cmpb(node s1,node s2){return s1.b<s2.b;}
inline void insert(int x,int v){for(;x<=n;x+=(-x)&x) d[x]+=v;}
inline int ask(int x){int s=0; for(;x;x-=x&(-x)) s+=d[x]; return s;}
void cdq(int l,int r){
if(l==r) return ; int mid=l+r>>1;
cdq(l,mid),cdq(mid+1,r); int j=l;
for(int i=mid+1;i<=r;i++){
while(j<=mid&&t[j].b<t[i].b) insert(t[j].c,1),j++;
res+=ask(t[i].c-1);
}
for(int i=l;i<j;i++) insert(t[i].c,-1);
sort(t+l,t+r+1,cmpb);
}
signed main(){
cin>>n;
for(int i=1;i<=n;i++) scanf("%d %d %d",&t[i].a,&t[i].b,&t[i].c);
sort(t+1,t+1+n,cmpa); cdq(1,n);
cout<<1LL*n*(n-1)/2-res;
return 0;
}