zoukankan      html  css  js  c++  java
  • HDU 4000 Fruit Ninja 树状数组 + 计数

    给你N的一个排列,求满足:a[i] < a[k] < a[j] 并且i < j < k的三元组有多少个。

    一步转化:

    求出所有满足 a[i] < a[k] < a[j] 并且i < j < k的三元组 与 a[i] < a[k] < a[j] 并且i < k < j的三元组 的个数的总和,设high[i]为在 i 右侧且大于a[i] 的数的个数,上述总和即为:high[i] * (high[i] - 1) / 2。

    设low[i]为在 i 左侧且小于a[i] 的数的个数, a[i] < a[k] < a[j] 并且i < k < j的三元组 的个数即为:low[i]*high[i]。

    答案即为:∑( high[i] * (high[i] - 1) / 2 - low[i]*high[i] );

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <algorithm>
     5 
     6 #define LL long long int
     7 
     8 using namespace std;
     9 
    10 const int MAXN = 100100;
    11 const LL MOD = 100000007;
    12 
    13 int N;
    14 int C[MAXN];
    15 int num[MAXN];
    16 int low[MAXN];
    17 int high[MAXN];
    18 
    19 int lowbit( int x )
    20 {
    21     return x & ( -x );
    22 }
    23 
    24 void Update( int x, int val )
    25 {
    26     while ( x <= N )
    27     {
    28         C[x] += val;
    29         x += lowbit(x);
    30     }
    31     return;
    32 }
    33 
    34 int Query( int x )
    35 {
    36     int res = 0;
    37     while ( x > 0 )
    38     {
    39         res += C[x];
    40         x -= lowbit(x);
    41     }
    42     return res;
    43 }
    44 
    45 int main()
    46 {
    47     int T, cas = 0;
    48     scanf( "%d", &T );
    49     while ( T-- )
    50     {
    51         scanf( "%d", &N );
    52         for ( int i = 1; i <= N; ++i )
    53             scanf( "%d", &num[i] );
    54 
    55         memset( C, 0, sizeof(C) );
    56 
    57         for ( int i = 1; i <= N; ++i )
    58         {
    59             low[i] = Query( num[i] - 1 );
    60             Update( num[i], 1 );
    61         }
    62 
    63         memset( C, 0, sizeof(C) );
    64         for ( int i = N; i > 0; --i )
    65         {
    66             //printf("i=%d %d %d
    ", i, Query( N ), Query( num[i] ) );
    67             high[i] = Query( N ) - Query( num[i] );
    68             Update( num[i], 1 );
    69         }
    70 
    71         LL ans = 0;
    72         for ( int i = 1; i <= N; ++i )
    73         {
    74             //printf( "h=%d l=%d
    ", high[i], low[i] );
    75             ans += (LL)high[i] * ( high[i] - 1 ) / 2 - (LL)low[i] * high[i];
    76             ans = ( ans + MOD ) % MOD;
    77         }
    78 
    79         printf( "Case #%d: %I64d
    ", ++cas, ans % MOD );
    80     }
    81     return 0;
    82 }
  • 相关阅读:
    AcWing 1135. 新年好 图论 枚举
    uva 10196 将军 模拟
    LeetCode 120. 三角形最小路径和 dp
    LeetCode 350. 两个数组的交集 II 哈希
    LeetCode 174. 地下城游戏 dp
    LeetCode 面试题 16.11.. 跳水板 模拟
    LeetCode 112. 路径总和 递归 树的遍历
    AcWing 1129. 热浪 spfa
    Thymeleaf Javascript 取值
    Thymeleaf Javascript 取值
  • 原文地址:https://www.cnblogs.com/GBRgbr/p/3236326.html
Copyright © 2011-2022 走看看