zoukankan      html  css  js  c++  java
  • UVA1428 Ping pong(树状数组)

    题目链接

    题意:

    n个人,从左到右排列,每个人都有一个不同的技能值 ai, 每场比赛3个人: 两名选手, 一名裁判。 裁判必须在两名选手中间, 并且技能值也在两名选手之间, 问一共能组织多少种比赛。

    分析:

      考虑第i个人当裁判的情形。假设 ai 到 ai-1 中有 ci 个比 ai 个小, 那么就有 (i-1)-ci 个比 ai 大; 同理, 假设 ai+1 到 an 中有di个比ai 小, 那么就有 (n-i)-di 个比 ai 大。 根据乘法原理和加法原理, i当裁判 有 ci(n-i-di)+(i-ci-1)*di 种比赛。 这样问题转化为求 ci 和 di.

      题目已经明确每个人都有一个不同的技能值。 那么要求 ci , 先将树状数组 x 清空, 从左到右扫描 ai , 每运行一次 add(ai, 1), 就运行一次 sum(ai-1), sum求的是比 ai 小的数的个数, 因为是依次添加, 求 ai 时, ai 右边的数是没有加入树状数组 x 的, 这样 sum(ai-1), 求的就是 在 i 左边的比 ai 小的数的个数, 即 ci。 同理可以计算出 di

    注意:

    有一个调试了4个多小时的BUG(欲哭无泪啊), 那就是 数组 x 的大小并不是 n , 因为 n 代表人的个数,而 x 存的值为技能值,  即 x 的大小为 a1~an 最大的技能值。

    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 100000 + 10;
    
    int c[20000+10], d[20000+10], x[maxn], a[20000+10], n, mn;
    
    int lowbit(int e) { return e & (-e); }
    
    void add(int p, int ad){
        while(p<=mn){   //这里是 mn, 并非 n
            x[p] += ad;
            p += lowbit(p);
        }
    }
    
    int sum(int p){
        int ret = 0;
        while(p > 0){
            ret += x[p];
            p -= lowbit(p);
        }
        return ret;
    }
    
    int main(){
        int T;
        scanf("%d", &T);
        while(T--){
            mn = 0;
    
            scanf("%d", &n);
    
            for(int i=1; i<=n; i++){
                scanf("%d", &a[i]);
                mn = max(mn, a[i]);
            }
    
            memset(x, 0, sizeof(x));
            for(int i=1; i<=n; i++){
                add(a[i], 1);
                c[i] = sum(a[i]-1);
            }
    
            memset(x, 0, sizeof(x));
            for(int i=n; i>=1; i--){
                add(a[i], 1);
                d[i] = sum(a[i]-1);
            }
    
            long long int ans = 0;
            for(int i=1; i<=n; i++){
                ans += (long long)c[i]*(n-i-d[i]) + (long long)(i-c[i]-1)*d[i];
            }
    
            printf("%lld\n", ans);
        }
    
        return 0;
    }
  • 相关阅读:
    75. Sort Colors
    101. Symmetric Tree
    121. Best Time to Buy and Sell Stock
    136. Single Number
    104. Maximum Depth of Binary Tree
    70. Climbing Stairs
    64. Minimum Path Sum
    62. Unique Paths
    css知识点3
    css知识点2
  • 原文地址:https://www.cnblogs.com/tanhehe/p/3065536.html
Copyright © 2011-2022 走看看