• PAT 1009. Triple Inversions (35) 数状数组


    Given a list of N integers A1, A2, A3,...AN, there's a famous problem to count the number of inversions in it. An inversion is defined as a pair of indices i < j such that Ai > Aj.

    Now we have a new challenging problem. You are supposed to count the number of triple inversions in it. As you may guess, a triple inversion is defined as a triple of indices i < j < k such that Ai > Aj > Ak. For example, in the list {5, 1, 4, 3, 2} there are 4 triple inversions, namely (5,4,3), (5,4,2), (5,3,2) and (4,3,2). To simplify the problem, the list A is given as a permutation of integers from 1 to N.

    Input Specification:

    Each input file contains one test case. For each case, the first line gives a positive integer N in [3, 105]. The second line contains a permutation of integers from 1 to N and each of the integer is separated by a single space.

    Output Specification:

    For each case, print in a line the number of triple inversions in the list.

    Sample Input:

    22
    1 2 3 4 5 16 6 7 8 9 10 19 11 12 14 15 17 18 21 22 20 13
    

    Sample Output:

    8

    题意:给定1~n的无序数列,求其中长度=3连续递减的字串个数,如样例:(16,14,13)。
    思路:愚蠢!愚蠢!刚开始找的是三个数中的最前一个,然而判断连续递减就有点困难(这题时间限制为300ms)。
    其实可以找中间的那个数,再向左查询比中间数大的数的个数,向右查询比中间数小的个数, 两侧相乘就是解了。
    最大的问题是如何记录大小,因为给定的是1~n连续的数,甚至不需用离散化,通过遍历到某个数,找比它小或大的是否已经被标记了,再标记这个数。
    快速求和操作显然要用到树状数组。
    噢,还有这题注意结果使用long long 为此而WA。
     1 #include <stdio.h>
     2 #include <iostream>
     3 #include <string.h>
     4 #include <algorithm>
     5 #define LL long long
     6 using namespace std;
     7 
     8 
     9 int n, c[100010], a[100010];
    10 LL l[100010], r[100010];
    11 void add(int x)  //增加操作 
    12 {
    13     while(x <= n)
    14     {
    15         c[x]++;
    16         x += x & (-x);
    17     }
    18 }
    19 
    20 int get(int x) //获取和 
    21 {
    22     int ans = 0;
    23     while(x)
    24     {
    25         ans +=c[x];
    26         x -= x & (-x);
    27     }
    28     return ans;
    29 }
    30 int main()
    31 {
    32     LL ans;
    33     while(cin >> n)
    34     {
    35         ans = 0;
    36         for(int i = 1; i <= n; i++)
    37         {
    38             scanf("%d", a + i);
    39             c[i] = 0;
    40         }
    41         for(int i = 1; i <= n; i++)
    42         {
    43             l[i] = i - 1 - get(a[i]);
    44             add(a[i]);
    45         }
    46         for(int i = 1; i <= n; i++)
    47             c[i] = 0;
    48         for(int i = 1; i <= n; i++)
    49         {
    50             r[i] = a[i] - 1 - get(a[i]);//为value - 左侧大于它的个数 
    51             add(a[i]);
    52         }
    53 
    54         for(int i = 1; i <= n; i++)
    55             ans += l[i]*r[i];
    56 
    57         printf("%lld
    ", ans);
    58     }
    59 }
    
    
    
     
  • 相关阅读:
    ARC108解题报告
    整体dp小结
    SAM学习笔记&AC自动机复习
    Error creating bean with name 'bootstrapImportSelectorConfiguration':
    responseBody
    无力回天的CSP2020
    NOIP2020游记
    2020国家集训队作业选做
    flutter开发使用AnnotatedRegion修改状态栏字体颜色,导致导航栏也变黑了的解决方法
    flutter使用InkWell点击没有水波纹效果的解决方法
  • 原文地址:https://www.cnblogs.com/Yumesenya/p/5451351.html
Copyright © 2020-2023  润新知