• LA 4329 (树状数组) Ping pong


    第一次写树状数组,感觉那个lowbit位运算用的相当厉害。

    因为-x相当于把x的二进制位取反然后整体再加上1,所以最右边的一个1以及末尾的0,取反加一以后不变。

    比如1000取反是0111加一得到1000,这样与运算以后不变

    最右边的1左边部分取反,加一不会影响左半部分,所以与运算以后全部为0

    对于这道题来说貌似不是很容易能联想到树状数组

    注意题中说了每个人的技能值互不相同。

    从左往右扫描每个a[i],另x[a[i]] = 1,然后统计x[1]...x[a[i]-1]的和就是第i个人左边技能值比他小的人数c[i],所以第i个人左边技能值比他大的人数就是i-1-c[i]

    同样地,从右往左扫描a[i],也另x[a[i]] = 1,统计x[1]...x[a[i]-1]的和就是这个人右边技能值比他小的人数d[i],所以他右边技能值比他大的人数就是n-i-d[i]

    在根据计数原理,求一下总的方案数就是sum{ c[i] * n-i-d[i] + d[i] * i-1-c[i] }

     1 #include <cstdio>
     2 #include <vector>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 inline int lowbit(int x) { return x & (-x); }
     7 
     8 struct Fenwicktree
     9 {
    10     int n;
    11     vector<int> C;
    12 
    13     void resize(int n) { this->n = n; C.resize(n); }
    14     void clear() { fill(C.begin(), C.end(), 0); }
    15 
    16     int sum(int x)
    17     {
    18         int ret = 0;
    19         while(x)
    20         {
    21             ret += C[x];
    22             x -= lowbit(x);
    23         }
    24         return ret;
    25     }
    26 
    27     void add(int x, int d)
    28     {
    29         while(x <= n)
    30         {
    31             C[x] += d;
    32             x += lowbit(x);
    33         }
    34     }
    35 }f;
    36 
    37 const int maxn = 20000 + 10;
    38 int a[maxn], c[maxn], d[maxn];
    39 
    40 int main()
    41 {
    42     //freopen("in.txt", "r", stdin);
    43 
    44     int T;
    45     scanf("%d", &T);
    46     while(T--)
    47     {
    48         int n, maxa = 0;
    49         scanf("%d", &n);
    50         for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); maxa = max(maxa, a[i]); }
    51         f.resize(maxa); f.clear();
    52         for(int i = 1; i <= n; i++)
    53         {
    54             f.add(a[i], 1);
    55             c[i] = f.sum(a[i] - 1);
    56         }
    57         f.clear();
    58         for(int i = n; i > 0; i--)
    59         {
    60             f.add(a[i], 1);
    61             d[i] = f.sum(a[i] - 1);
    62         }
    63         long long ans = 0;
    64         for(int i = 1; i <= n; i++) ans += (long long)c[i]*(n-i-d[i]) + (long long)d[i]*(i-1-c[i]);
    65         printf("%lld
    ", ans);
    66     }
    67 
    68     return 0;
    69 }
    代码君
  • 相关阅读:
    常用HTTP Contenttype头信息及文件类型对照
    Web开发专用IDE:Aptana Studio 3.0
    如果张柏芝的孩子长大
    Apache日志分析工具Awstats的安装和配置
    台北貢寮~三貂角燈塔
    [转]ASP,PHP,JSP,ASP.NET 比较
    联想 Thinkpad SL410使用体验
    2011年6月TIOBE编程语言走势图及指数
    百度搜索能力越来越差了,看下图
    PHP 5.3.x中弃用的特性 Deprecated
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4342704.html
Copyright © 2020-2023  润新知