链接:
https://www.nowcoder.com/questionTerminal/1e9d3c4b48b34dafb87b5ee883ffedc4
来源:牛客网
来源:牛客网
[编程题]Contest
- 热度指数:657时间限制:1秒空间限制:131072K
- 算法知识视频讲解
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;
}