zoukankan      html  css  js  c++  java
  • HDU 5792

    题意:

      给出序列 A,

      求满足 a<b,c<d, A[a] < A[b] , A[c] > A[d] 的互不相同的 (a,b,c,d) 的对数

      分析:

      a<b, A[a] < A[b] 为顺序对, c<d, A[c] > A[d] 为逆序对

      故先求出所有顺序对和逆序对的乘积,再减去重复的,即四个数中有任意两个相等的情况

        重复的有以下四种:

          a == c  b,d > a,c

          b == d  a,c < b,d

          b == c  a < b,c < d

          a == d  c < a,d < b

        故对于每个 i ,答案均要减去这四种重复的

      顺逆序对可用树状数组求

      首先要离散化,再要考虑有相同数字的情况

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstring>
     5 using namespace std;
     6 const int MAXN = 50005;
     7 int c[MAXN], top;
     8 void modify(int x,int num)
     9 {
    10     while (x <= top) c[x] += num, x += x&-x;
    11 }
    12 int query(int x)
    13 {
    14     int s = 0;
    15     while (x > 0) s+= c[x], x -= x&-x;
    16     return s;
    17 }
    18 int n;
    19 int a[MAXN], b[MAXN];
    20 struct Node
    21 {
    22     long long preS, preL, subS, subL;//pre smaller , pre larger , sub smaller , sub larger
    23 }s[MAXN];
    24 long long ans, sumL, sumS;//逆序对,顺序对 
    25 void Init()
    26 {
    27     for (int i = 0; i < n; i++) b[i] = a[i];
    28     sort(b, b + n);
    29     int size = unique(b,b+n) - b;
    30     sumL = sumS = top = 0;
    31     for (int i = 0; i < n; i++)//离散化 
    32     {
    33         a[i] = lower_bound(b,b+size,a[i]) - b + 1;
    34         top = max(top, a[i]);
    35     }
    36     memset(c, 0, sizeof(c));
    37     for (int i = 0; i < n; i++)
    38     {
    39         s[i].preS = query(a[i] - 1);
    40         s[i].preL = i - query(a[i]);
    41         sumL += s[i].preL;
    42         sumS += s[i].preS;
    43         modify(a[i], 1);
    44     }
    45     memset(c, 0, sizeof(c));
    46     for (int i = n-1; i >= 0; i--)
    47     {
    48         s[i].subS = query(a[i] - 1);
    49         s[i].subL = (n-1 - i) - query(a[i]);
    50         modify(a[i], 1);        
    51     }
    52 }
    53 int main()
    54 {
    55     while(~scanf("%d", &n))
    56     {
    57         for (int i = 0; i < n; i++)
    58             scanf("%d", &a[i]);
    59         Init();
    60         ans = sumL * sumS ;
    61         for (int i = 0; i < n; i++)
    62         {
    63             ans -= s[i].subL * s[i].subS;// a == c  b,d > a,c 
    64             ans -= s[i].preL * s[i].preS;// b == d  a,c < b,d
    65             ans -= s[i].subS * s[i].preS;// b == c  a < b,c < d
    66             ans -= s[i].preL * s[i].subL;// a == d  c < a,d < b
    67         }
    68         printf("%I64d
    ", ans);
    69     }
    70 }
    我自倾杯,君且随意
  • 相关阅读:
    UVA 11925 Generating Permutations 生成排列 (序列)
    UVA 1611 Crane 起重机 (子问题)
    UVA 11572 Unique snowflakes (滑窗)
    UVA 177 PaperFolding 折纸痕 (分形,递归)
    UVA 11491 Erasing and Winning 奖品的价值 (贪心)
    UVA1610 PartyGame 聚会游戏(细节题)
    UVA 1149 Bin Packing 装箱(贪心)
    topcpder SRM 664 div2 A,B,C BearCheats , BearPlays equalPiles , BearSorts (映射)
    UVA 1442 Cave 洞穴 (贪心+扫描)
    UVA 1609 Foul Play 不公平竞赛 (构(luan)造(gao)+递归)
  • 原文地址:https://www.cnblogs.com/nicetomeetu/p/5749432.html
Copyright © 2011-2022 走看看