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

来源:互联网 发布:nginx 配置证书链 编辑:程序博客网 时间:2024/04/30 14:40
链接: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

输入

41 3 12 2 44 1 23 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);elseans+=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];elseq[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;}