您的位置:首页 > 其它

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

2017-09-19 22:37 337 查看
链接: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)算一组。

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


[b]输出描述:[/b]
输出一个整数表示满足条件的(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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: