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

输入描述:
第一行一个整数n,表示队伍数; 接下来n行,每行三个整数a[i], b[i], c[i],分别表示i在第一场、第二场和第三场比赛中的名次;n 最大不超过200000

输出描述:
输出一个整数表示满足条件的(x,y)数;64bit请用lld

题解
我们知道这里是求三次逆序对,先把第一场比赛的排名作序号,跟第二场比赛排名求逆序对的数量,再把第一场和第三场一起求,然后把第二场和第三场一起求这样会产生一些重复的,我们知道,如果两只队伍被计入逆序对,那么必有一只队伍排名高一场,则另一只队伍排名必高两场,比如x1<y1,x2>y2,x3>y3,那么就会有两组逆序对,所以要除以二

代码

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define lowbit(x) x&(-x)

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll, ll> pll;

const int N = 2e5+5;
const ll mod = 1e9+7;
const int INF = 0x3f3f3f3f;
const double eps =1e-9;
const double PI=acos(-1.0);
const int dir[4][2]={-1,0,1,0,0,-1,0,1};
const int exdir[4][2]={1,1,1,-1,-1,1,-1,-1};

ll qpow(ll x,ll y){
    ll ans=1,t=x;
    while(y>0){
        if(y&1)ans*=t,ans%=mod;
        t*=t,t%=mod;
        y>>=1;
    }
    return ans%mod;
}

struct node{
    int a,b,c;
}a[N];
int tree[N],n;

bool cmp1(node a,node b){
    return a.a<b.a;
}
bool cmp2(node a,node b){
    return a.b<b.b;
}

void add(int x){
    while(x<=n){tree[x]+=1;x+=lowbit(x);}
}
int sum(int x){
    int ans = 0;
    while(x>0){ans+=tree[x];x-=lowbit(x);}
    return ans;
}
void solve(){
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i].a>>a[i].b>>a[i].c;
    ll ans=0;
    sort(a+1,a+n+1,cmp1);
    for(int i=1;i<=n;i++){
        ans+= sum(n)-sum(a[i].b);
        add(a[i].b);
    }
    memset(tree,0,sizeof(tree));
    for(int i=1;i<=n;i++){
        ans +=sum(n)-sum(a[i].c);
        add(a[i].c);
    }
    memset(tree,0,sizeof(tree));
    sort(a+1,a+n+1,cmp2);
    for(int i=1;i<=n;i++){
        ans += sum(n)-sum(a[i].c);
        add(a[i].c);
    }
    cout<<ans/2;
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    //int t;cin>>t;
    //while(t--)solve(),cout<<'\n';
    solve();
    return 0;
}