zoukankan      html  css  js  c++  java
  • 牛客网 Wannafly模拟赛2 A  Contest(树状数组求逆序对)

    时间限制: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


    分析: 从题目中的表述可以想到逆序对,这里的话就是求三次逆序对,
    先把第一场比赛的排名作序号,跟第二场比赛排名求逆序对的数量
    再把第一场和第三场一起求,然后把第二场和第三场一起求
    这样会产生一些重复的.
    我们知道,如果两只队伍被计入逆序对
    那么一只队伍排名高一场,另一只队伍排名必然高两次,算逆序对的时候,会被计算两次.
    所以将逆序对的数量除以二就能得到最终答案
    代码如下:
    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <map>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const int MAXN=200010;
    int c[MAXN];
    int n;
    int a[MAXN];
    int cnt;
    struct node2
    {
        int x;
        int y;
        int z;
    }peo[200100];
    struct node
    {
        int id;
        ll num;
    }r[MAXN];
    int cmp(node x,node y)
    {
        if(x.num!=y.num)
        return x.num<y.num;
        else
       return x.id<y.id;
    }
    int lowbit(int x)
    {
        return x&(-x);
    }
    void add(int i,int value)
    {
     
        while(i<=n)
        {
            c[i]+=value;
            i+=lowbit(i);
        }
    }
    int  sum(int i)
    {
        int sum=0;
        while(i>=1)
        {
          sum+=c[i];
          i-=lowbit(i);
        }
        return sum;
    }
    int main()
    {
        int t,i,tmp;
        ll ans;
     
            ans=0;
            while(scanf("%d",&n)!=EOF){
            for(int i=1;i<=n;i++)
            {
                 scanf("%d%d%d",&peo[i].x,&peo[i].y,&peo[i].z);
            }
            memset(c,0,sizeof(c));
            memset(r,0,sizeof(r));
            for(i=1;i<=n;i++)
            {
              r[i].num=peo[i].y;
              r[i].id=peo[i].x;
            }
            sort(r+1,r+n+1,cmp);
     
            for(int j=1;j<=n;j++)
            {
                         add(r[j].id,1);
                       ans+=j-sum(r[j].id);
            }
     
           memset(c,0,sizeof(c));
            for(i=1;i<=n;i++)
            {
              r[i].num=peo[i].z;
              r[i].id=peo[i].x;
            }
            sort(r+1,r+n+1,cmp);
     
            for(int j=1;j<=n;j++)
            {
                         add(r[j].id,1);
                       ans+=j-sum(r[j].id);
            }
     
            memset(c,0,sizeof(c));
            for(i=1;i<=n;i++)
            {
              r[i].num=peo[i].z;
              r[i].id=peo[i].y;
            }
            sort(r+1,r+n+1,cmp);
     
            for(int j=1;j<=n;j++)
            {
                         add(r[j].id,1);
                       ans+=j-sum(r[j].id);
            }
            printf("%lld
    ",ans/2);
        }
        return 0;
    }
  • 相关阅读:
    ASP.NET编程的十大技巧
    C#学习心得(转)
    POJ 1177 Picture (线段树)
    POJ 3067 Japan (树状数组)
    POJ 2828 Buy Tickets (线段树)
    POJ 1195 Mobile phones (二维树状数组)
    HDU 4235 Flowers (线段树)
    POJ 2886 Who Gets the Most Candies? (线段树)
    POJ 2418 Cows (树状数组)
    HDU 4339 Query (线段树)
  • 原文地址:https://www.cnblogs.com/a249189046/p/7526344.html
Copyright © 2011-2022 走看看