zoukankan      html  css  js  c++  java
  • 牛客练习赛2 A

    链接:https://www.nowcoder.com/acm/contest/4/A
    来源:牛客网

    题目描述

    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$分治。

    总的方案数有$n*(n - 1) / 2$种,不满足条件的就是三维偏序,减去即可。

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn = 2e5 + 10;
    struct X {
      int a, b, c;
      int id;
    }s[maxn];
    int n;
    int f[maxn];
    int c[maxn];
    
    int lowbit(int x) {
      return x & (-x);
    }
    
    void update(int p, int v) {
      for(int i = p; i < maxn; i = i + lowbit(i)) {
        c[i] += v;
      }
    }
    
    int sum(int p) {
      int res = 0;
      while(p) {
        res += c[p];
        p -= lowbit(p);
      }
      return res;
    }
    
    bool cmpA(const X& a, const X& b) {
      return a.a < b.a;
    }
    
    bool cmpB(const X& a, const X& b) {
      return a.b < b.b;
    }
    
    bool cmpID(const X& a, const X& b) {
      return a.id < b.id;
    }
    
    void cdq(int L, int R) {
      if(L == R) return;
      int mid = (L + R) / 2;
      sort(s + L, s + mid + 1, cmpB);
      sort(s + mid + 1, s + R + 1, cmpB);
      int p1 = L;
      for(int i = mid + 1; i <= R; i ++) {
        while(p1 <= mid && s[p1].b <= s[i].b) {
          update(s[p1].c, 1);
          p1 ++;
        }
        f[s[i].id] += sum(s[i].c);
      }
      for(int i = L; i < p1; i ++) {
        update(s[i].c, -1);
      }
      sort(s + L, s + mid + 1, cmpID);
      sort(s + mid + 1, s + R + 1, cmpID);
      cdq(L, mid);
      cdq(mid + 1, R);
    }
    
    int main() {
      scanf("%d", &n);
      for(int i = 1; i <= n; i ++) {
        scanf("%d%d%d", &s[i].a, &s[i].b, &s[i].c);
      }
      sort(s + 1, s + 1 + n, cmpA);
      for(int i = 1; i <= n; i ++) {
        s[i].id = i;
      //  printf("%d %d %d %d
    ", s[i].a, s[i].b, s[i].c, s[i].id);
      }
      cdq(1, n);
      long long A = 1LL * n;
      long long B = 1LL * (n - 1);
      long long C = 0;
      if(A % 2 == 0) A = A / 2;
      else B = B / 2;
      for(int i = 1; i <= n; i ++) {
        C = C + 1LL * f[i];
      }
      printf("%lld
    ", A * B - C);
      
      return 0;
    }
    
  • 相关阅读:
    python CST中国标准时间格式转换
    pytest+报告插件
    getopt实现命令行
    初识Redis
    python list 切片及翻转的使用
    mysql中information_schema表
    获取两个字符串中最长的相同子串
    mongodb数据库备份
    VS2005下边不能使用target>remote tool解决方法
    wince LoadDriver tool
  • 原文地址:https://www.cnblogs.com/zufezzt/p/8365361.html
Copyright © 2011-2022 走看看