Wannafly模拟赛2-Contest(CDQ分治)

链接: https://www.nowcoder.com/questionTerminal/1e9d3c4b48b34dafb87b5ee883ffedc4
来源:牛客网

[编程题]Contest
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
示例1

输入

4
1 3 1
2 2 4
4 1 2
3 4 3

输出

5

说明

 
     
CDQ分治模板题:一维直接排序,二维树状数组,三维CDQ分治就好了。
#include<set>  
#include<map>     
#include<stack>            
#include<queue>            
#include<vector>    
#include<string> 
#include<time.h>
#include<math.h>            
#include<stdio.h>            
#include<iostream>            
#include<string.h>            
#include<stdlib.h>    
#include<algorithm>   
#include<functional>    
using namespace std;            
#define ll long long        
#define inf  1000000000       
#define mod 1000000007             
#define maxn  200010
#define lowbit(x) (x&-x)            
#define eps 1e-9 
struct node
{
	ll x,y,z;
	bool operator <(const node &b) const
	{
		if(x<b.x || x==b.x && y<b.y || x==b.x && y==b.y && z<b.z)
			return 1;
		return 0;
	}
}q[maxn*8],a[maxn*8];
ll n,ans,num,sum[maxn*8];
void update(int x,int val)
{
	while(x<=n)
	{
		sum[x]+=val;
		x+=lowbit(x);
	}
}
int query(int x)
{
	int res=0;
	while(x)
	{
		res+=sum[x];
		x-=lowbit(x);
	}
	return res;
}
void cdq(int l,int r)
{
	if(l==r)
		return;
	int i,m=(l+r)/2;
	for(i=l;i<=r;i++)
	{
		if(a[i].z<=m)
			update(a[i].y,1);
		else
			ans+=query(a[i].y);
	}
	for(i=l;i<=r;i++)
		if(a[i].z<=m)
			update(a[i].y,-1);
	int lq=l,rq=m+1;
	for(i=l;i<=r;i++)
	{
		if(a[i].z<=m)
			q[lq++]=a[i];
		else
			q[rq++]=a[i];
	}
	for(i=l;i<=r;i++)
		a[i]=q[i];
	cdq(l,m);cdq(m+1,r);
}
int main(void)
{
	int i;
	scanf("%lld",&n);
	for(i=1;i<=n;i++)
		scanf("%lld%lld%lld",&a[i].x,&a[i].y,&a[i].z);
	sort(a+1,a+n+1);
	cdq(1,n);
	printf("%lld\n",n*(n-1)/2-ans);
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值