• UVA 1428 Ping pong 二叉索引树标准用法 Anti


    分析:

      感觉白书写的不太好理解,说下自己稍微改动后的分析。

      想象一条数轴,数轴上的点表示能力值。

      用数组c[i]表示在二叉索引树中以a[i]结尾的“水平长条”。

      所以每输入一个能力值都要更新与之相关的c[i]的值。

      第i个人当裁判时,

      计算到目前为止(即a[1]到a[i-1])数轴上a[i]左边的标记的个数,即前缀和,存入front[i],则a[i]右边就有i-1-front[i]个。

      重新逆序计算到目前为止(即a[n]到a[i+1])数轴上a[i]左边的标记的个数,即前缀和,存入back[i],则a[i]右边就有n-i-back[i]。

      说的很乱。。意会就好了。。这是我的代码:

    #include <stdio.h>
    #include <string.h>
    
    int t, n, a[20010], c[100010], front[20010], back[20010];
    
    int lowbit(int x)
    {
        return x & -x;
    }
    
    int sum(int x)
    {
        int ans = 0;
        while(x > 0)
        {
            ans += c[x];
            x -= lowbit(x);
        }
        return ans;
    }
    
    void add(int x, int d)
    {
        while(x <= 100000)
        {
            c[x] += d;
            x += lowbit(x);
        }
    }
    
    int main()
    {
        scanf("%d", &t);
        while(t--)
        {
            scanf("%d", &n);
            memset(c, 0, sizeof(c));
            for(int i = 1; i <= n; i++)
            {
                scanf("%d", &a[i]);
                add(a[i], 1);
                front[i] = sum(a[i]-1);
            }
            memset(c, 0, sizeof(c));
            for(int i = n; i >= 1; i--)
            {
                add(a[i], 1);
                back[i] = sum(a[i]-1);
            }
            long long ans = 0;
            for(int i = 2; i < n; i++)
                ans += 1LL * front[i]*(n-i-back[i]) + (i-front[i]-1)*back[i];
            printf("%lld\n", ans);
        }
        return 0;
    }

      

  • 相关阅读:
    计算机网络知识 第一部分
    LAMP环境安装
    Axure RP 交互设计
    Axure RP 界面功能
    Axure RP 界面功能介绍
    Axure RP 第一部分
    Grub管理修改root口令
    MYSQL 部分练习题
    工作日志示例
    计算机网络的分类
  • 原文地址:https://www.cnblogs.com/wolfred7464/p/3105721.html
Copyright © 2020-2023  润新知