Codeforces GYM100247 K. Three Contests 题解

181 阅读1分钟

题目链接

思路

记第ii支队伍在第一场比赛中排名为aia_i,第二场为bib_i,第三场为cic_i

考虑先按第一维排序,下标大的必定在第一场比赛中赢过下标小的,那么任意bi>bj(i<j)b_i>b_j(i<j)ci>cj(i<j)c_i>c_j(i<j)都可以贡献答案,用树状数组计算两次二维偏序。但是其中会有重复贡献的答案,即对于某一对(i,j)(i,j),存在bi>bj,ci>cjb_i>b_j,c_i>c_j,因此还要减去重复贡献的答案,即满足ai<aj,bi>bj,ci>cja_i<a_j,b_i>b_j,c_i>c_j的数对(i,j)(i,j)的个数,是一个三位偏序问题,用cdq分治解决。

代码

#include<bits/stdc++.h>
#define rep(i,st,ed) for(int i=st;i<=ed;++i)
#define bl(u,i) for(int i=head[u];i;i=e[i].nxt)
#define lb(x) x&-x;
#define LLM LONG_LONG_MAX
#define LLm LONG_LONG_MIN
#define pii pair<ll,ll> 
typedef long long ll;
typedef double db;
using namespace std;
const ll INF=0x3f3f3f3f;
inline void In(ll _,...)
{
	va_list lis;
	va_start(lis,_);
	while(_--)
		scanf("%lld",va_arg(lis,ll*));
}
inline void Out(ll _,...)
{
	va_list lis;
	va_start(lis,_);
	while(_--)
		printf("%lld\n",va_arg(lis,ll));
}
inline void Out_(ll _,...)
{
	va_list lis;
	va_start(lis,_);
	while(_--)
		printf("%lld ",va_arg(lis,ll));
}
const ll N=2E5+10;
ll n,ans;
ll t[N];
struct Node{
	ll x,y,z;
}a[N];
bool cmpx(const Node &u,const Node &v)
{
	if(u.x==v.x)
	{
		if(u.y==v.y)
			return u.z<v.z;
		return u.y<v.y;
	}
	return u.x<v.x;
}
bool cmpy(const Node &u,const Node &v)
{
	if(u.y==v.y)
		return u.z>v.z;
	return u.y>v.y;
}
void add(ll x,ll val)
{
	while(x<=n)
	{
		t[x]+=val;
		x+=lb(x);
	}
}
ll query(ll x)
{
	ll ret=0;
	while(x)
	{
		ret+=t[x];
		x-=lb(x);
	}
	return ret;
}
void cdq(ll l,ll r)
{
	if(l==r)
		return;
	ll mid=(l+r)>>1;
	cdq(l,mid);
	cdq(mid+1,r);
	ll ind=l;
	sort(a+l,a+mid+1,cmpy);
	sort(a+mid+1,a+r+1,cmpy);
	rep(i,mid+1,r)
	{
		while(ind<=mid && a[ind].y>a[i].y)
		{
			add(a[ind].z,1);
			++ind;
		}
		ans-=query(n)-query(a[i].z);
	}
	rep(i,l,ind-1)
		add(a[i].z,-1);
}
int main()
{
	In(1,&n);
	rep(i,1,n)
		In(3,&a[i].x,&a[i].y,&a[i].z);
	sort(a+1,a+n+1,cmpx);
	rep(i,1,n)
	{
		ans+=query(n)-query(a[i].y);
		add(a[i].y,1);
	}
	rep(i,1,n)
		t[i]=0;
	rep(i,1,n)
	{
		ans+=query(n)-query(a[i].z);
		add(a[i].z,1);
	}
	rep(i,1,n)
		t[i]=0;
	cdq(1,n);
	cout<<ans<<endl;
}