首页 > 编程语言 > 详细

contese(归并排序+思维)

时间:2020-10-22 22:30:59      阅读:35      评论:0      收藏:0      [点我收藏+]

题目链接:https://ac.nowcoder.com/acm/problem/13947

题目描述
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

题解
我们知道这里是求三次逆序对,先把第一场比赛的排名作序号,跟第二场比赛排名求逆序对的数量,再把第一场和第三场一起求,然后把第二场和第三场一起求这样会产生一些重复的,我们知道,如果两只队伍被计入逆序对,那么必有一只队伍排名高一场,则另一只队伍排名必高两场,比如x1<y1,x2>y2,x3>y3,那么就会有两组逆序对,所以要除以二(这一点仔细理解琢磨一下)

详情看代码:

#include<bits/stdc++.h>
#include<cstdio>
#define ll long long
const int MMAX=2e5+5;
int a[MMAX],b[MMAX],c[MMAX];
int te[MMAX],n;
ll ans=0;
void sor(int l1,int r1,int l2,int r2)
{
    int temp[MMAX];
    int i=l1,j=l2,re=0;
    while(i<=r1&&j<=r2)
    {
        if(te[i]<te[j]) temp[++re]=te[i++];
        else{
            ans=ans+r1-i+1;
            temp[++re]=te[j++];
        }
    }

    while(i<=r1) temp[++re]=te[i++];
    while(j<=r2) temp[++re]=te[j++];
    for(int i=1;i<=re;i++)
        te[i+l1-1]=temp[i];
}
void get_sort(int l,int r)
{
    int mid=(l+r)/2;
    if(mid!=l) get_sort(l,mid);
    if(r!=mid+1) get_sort(mid+1,r);
    sor(l,mid,mid+1,r);
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d%d%d",&a[i],&b[i],&c[i]);
    for(int i=1;i<=n;i++) te[a[i]]=b[i]; ///求(1,2)的逆序对
    get_sort(1,n);
    for(int i=1;i<=n;i++) te[a[i]]=c[i]; ///求(1,3)的逆序对
    get_sort(1,n);
    for(int i=1;i<=n;i++) te[b[i]]=c[i]; ///求(2,3)的逆序对
    get_sort(1,n);
    printf("%lld\n",ans/2);
    return 0;
}

 

contese(归并排序+思维)

原文:https://www.cnblogs.com/lhhhhh/p/13861146.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!