Problem:

n支队伍一共参加了三场比赛。
一支队伍x认为自己比另一支队伍y强当且仅当x在至少一场比赛中比y的排名高。
求有多少组(x,y),使得x自己觉得比y强,y自己也觉得比x强。
(x, y), (y, x)算一组。

Solution:

使得x自己觉得比y强,y自己也觉得比x强,即对于x和y来说,在3场比赛中存在x的排名大于y,y的排名大于x。
在题目中每个人有3场比赛的排名,若我们将第一场比赛排名按从大到小排序后,然后遍历的时候从头遍历,
这样其实就已经消除了一场比赛的影响,只需要考虑剩下的第二场比赛了,其实有经验的人可以看出这题题目和偏序有关,
( 一维偏序就是不需要处理,直接求逆序对
二维偏序就是将第一维排序后再求第二维的逆序对数
三维偏序就是 一维排序,二维分治,三维树状数组 -- 》 cdq分治

由于题目中给出了问题是求解有多少对(x,y)满足在3场比赛中存在x的排名大于y,y的排名大于x,所以我们用二维偏序即可解决,
对于能够满足需要的(x,y)来说,有这三种比赛结果满足(第一场(x1>y1),第二场(x2<y2))(第一场(x1>y1),第三场(x3<y3))(第二场(x2>y2),第三场(x3<y3))
由于上面只要有一种情况出现,那么一定就会出现两种(因为排名不会出现同样的。若x1>y1 & x2<y2,那么一定会出现((x1>y1) & (x3<y3) 和(x2>y2)&(x3<y3)中其中一种,其它的同理)
首先一维排好序后,求(二维的逆序对数 + 三维的逆序对数)
然后二维排好序后,求(三维的逆序对数)
最终将结果/2就是答案

tip:

对于题目的求解,当有2个不确定问题时,我们应该看是否能固定一个问题,然后使其只剩下一个待解决的问题 ,有可能只有一个需要解决时,它会变成你熟悉的问题。

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define _for(i,s,t) for(int i=s;i<t;i++)
#define _rof(i,s,t) for(int i=s;i>t;i--)
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define per(i,s,t) for(int i=s;i>=t;i--)
#define Ri(x) scanf("%d",&x)
#define Rii(x,y) scanf("%d%d",&x,&y)
#define INF 0x3f3f3f3f
using namespace std;
template<class T>inline void read(T &res)
{
    char c;T flag=1;
    while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
    while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
}
typedef long long ll;
const int maxn = 2e5 + 10;
int n,c[maxn];
struct Node{
    int a,b,c;
}nd[maxn];
bool cmp1(Node nd1,Node nd2){
    return nd1.a > nd2.a;
}
bool cmp2(Node nd1,Node nd2){
    return nd1.b > nd2.b;
}
int lowbit(int x){
    return x & (-x);
}
void add(int i,int v){
    while(i <= n){
        c[i] += v;
        i += lowbit(i);
    }
}
ll query(int i){
    ll result = 0;
    while(i > 0){
        result += c[i];
        i -= lowbit(i);
    }
    return result;
}
int main(){
    IOS;
    cin>>n;
    rep(i,1,n){
        cin>>nd[i].a>>nd[i].b>>nd[i].c;
    }
    sort(nd + 1,nd + 1 + n,cmp1);
    ll ans = 0;
    rep(i,1,n){
        ans += query(nd[i].b);
        add(nd[i].b,1);
    }
    memset(c,0,sizeof(c));
    rep(i,1,n){
        ans += query(nd[i].c);
        add(nd[i].c,1);
    }
    sort(nd + 1,nd + 1 + n,cmp2);
    memset(c,0,sizeof(c));
    rep(i,1,n){
        ans += query(nd[i].c);
        add(nd[i].c,1);
    }
    cout<<ans/2<<endl;
    return 0;
}
/**
Problem:
n支队伍一共参加了三场比赛。
一支队伍x认为自己比另一支队伍y强当且仅当x在至少一场比赛中比y的排名高。
求有多少组(x,y),使得x自己觉得比y强,y自己也觉得比x强。
(x, y), (y, x)算一组。

Solution:
使得x自己觉得比y强,y自己也觉得比x强,即对于x和y来说,在3场比赛中存在x的排名大于y,y的排名大于x。
在题目中每个人有3场比赛的排名,若我们将第一场比赛排名按从大到小排序后,然后遍历的时候从头遍历,
这样其实就已经消除了一场比赛的影响,只需要考虑剩下的第二场比赛了,其实有经验的人可以看出这题题目和偏序有关,
(    一维偏序就是不需要处理,直接求逆序对
    二维偏序就是将第一维排序后再求第二维的逆序对数
    三维偏序就是 一维排序,二维分治,三维树状数组 -- 》 cdq分治 
)
由于题目中给出了问题是求解有多少对(x,y)满足在3场比赛中存在x的排名大于y,y的排名大于x,所以我们用二维偏序即可解决,
对于能够满足需要的(x,y)来说,有这三种比赛结果满足(第一场(x1>y1),第二场(x2<y2))(第一场(x1>y1),第三场(x3<y3))(第二场(x2>y2),第三场(x3<y3))
由于上面只要有一种情况出现,那么一定就会出现两种(因为排名不会出现同样的。若x1>y1 & x2<y2,那么一定会出现((x1>y1) & (x3<y3) 和(x2>y2)&(x3<y3)中其中一种,其它的同理) 
首先一维排好序后,求(二维的逆序对数 + 三维的逆序对数)
然后二维排好序后,求(三维的逆序对数)
最终将结果/2就是答案 

tip:对于题目的求解,当有2个不确定问题时,我们应该看是否能固定一个问题,然后使其只剩下一个待解决的问题 ,有可能只有一个需要解决时,它会变成你熟悉的问题。 
*/