zoukankan      html  css  js  c++  java
  • 树状数组之求逆对数

     Ultra-QuickSort

     
     
    In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input sequence 
    9 1 0 5 4 ,

    Ultra-QuickSort produces the output 
    0 1 4 5 9 .

    Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence.

    Input

    The input contains several test cases. Every test case begins with a line that contains a single integer n < 500,000 -- the length of the input sequence. Each of the the following n lines contains a single integer 0 ≤ a[i] ≤ 999,999,999, the i-th input sequence element. Input is terminated by a sequence of length n = 0. This sequence must not be processed.

    Output

    For every input sequence, your program prints a single line containing an integer number op, the minimum number of swap operations necessary to sort the given input sequence.

    Sample Input

    5
    9
    1
    0
    5
    4
    3
    1
    2
    3
    0
    

    Sample Output

    6
    0

    题目是求每个数前面比它大的数量的总和,就是逆对数了。只要是离散化就可以做了。i-query(index[i]):当前是对i个数,query(index[i])是它前面比它小的数,减去它就是前面比它大的数量了。
     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <algorithm>
     5 #define lowbit(x) x&(-x)
     6 #define ll long long
     7 using namespace std;
     8 const int MAX = 5e5+5;
     9 int n, tree[MAX],index[MAX];
    10 struct Nod{
    11     int num,id;
    12 }nod[MAX];
    13 bool cmp(Nod a, Nod b){
    14     return a.num < b.num;
    15 }
    16 void add(int x, int y){
    17     while(x < MAX){
    18         tree[x] += y;
    19         x += lowbit(x);
    20     }
    21 }
    22 
    23 int query(int x){
    24     int sum = 0;
    25     while(x > 0){
    26         sum += tree[x];
    27         x -= lowbit(x);
    28     }
    29     return sum;
    30 }
    31 int main(){
    32     while(scanf("%d",&n)&&n){
    33         for(int i = 1; i <= n; i ++){
    34             scanf("%d",&nod[i].num);
    35             nod[i].id = i;
    36         }
    37         sort(nod+1,nod+1+n,cmp);
    38         for(int i = 1; i <= n; i ++)index[nod[i].id] = i;
    39         memset(tree,0,sizeof(tree));
    40         ll ans = 0;
    41         for(int i = 1; i <= n; i ++){
    42             add(index[i],1);
    43             //printf("%d+++++%d
    ",index[i],query(index[i]));
    44             ans += i-query(index[i]);
    45         }
    46         printf("%lld
    ",ans);
    47     }
    48 }

    Enemy is weak

     

    The Romans have attacked again. This time they are much more than the Persians but Shapur is ready to defeat them. He says: "A lion is never afraid of a hundred sheep".

    Nevertheless Shapur has to find weaknesses in the Roman army to defeat them. So he gives the army a weakness number.

    In Shapur's opinion the weakness of an army is equal to the number of tripletsi, j, k such that i < j < k and ai > aj > ak where ax is the power of man standing at position x. The Roman army has one special trait — powers of all the people in it are distinct.

    Help Shapur find out how weak the Romans are.

    Input

    The first line of input contains a single number n (3 ≤ n ≤ 106) — the number of men in Roman army. Next line contains n different positive integers ai (1 ≤ i ≤ n, 1 ≤ ai ≤ 109) — powers of men in the Roman army.

    Output

    A single integer number, the weakness of the Roman army.

    Please, do not use %lld specificator to read or write 64-bit integers in C++. It is preffered to use cout (also you may use %I64d).

    Example

    Input
    3
    3 2 1
    Output
    1
    Input
    3
    2 3 1
    Output
    0
    Input
    4
    10 8 3 1
    Output
    4
    Input
    4
    1 5 4 3
    Output
    1


    这个就是求三个递增的数量,也可以看成第i个数,求前面比它大的数量和后面比它小的数量。下面k是前面比它大的数量,
    求后面比它小的数量:由于k是第i个数前面比第i个数大的数量,所以后面比第i个数小的数量
                     为(n-index[i])-(i-1-k)就是n-i-index[i]+k+1,(n-index[i])是比第i个数小的
                     总数,把它减去前面比第i个数小的数量就是后面的数量了,前面比第i个数小的
                     数量为(i-1-k),所以(n-index[i])-(i-1-k)就推来了
     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <algorithm>
     5 #define lowbit(x) x&(-x)
     6 #define ll long long
     7 using namespace std;
     8 const int MAX = 1e6+10;
     9 int n,tree[MAX],index[MAX];
    10 int nex[MAX],pre[MAX];
    11 struct Nod{
    12     int val,id;
    13 }nod[MAX];
    14 bool cmp(Nod a, Nod b){
    15     return a.val > b.val;
    16 }
    17 void add(int x){
    18     while(x < MAX){
    19         tree[x] ++;
    20         x += lowbit(x);
    21     }
    22 }
    23 int query(int x){
    24     int sum = 0;
    25     while(x > 0){
    26         sum += tree[x];
    27         x -= lowbit(x);
    28     }
    29     return sum;
    30 }
    31 int main(){
    32     scanf("%d",&n);
    33     for(int i = 1; i <= n; i ++)scanf("%d",&nod[i].val),nod[i].id=i;
    34     sort(nod+1,nod+1+n,cmp);
    35     for(int i = 1; i <= n; i ++)index[nod[i].id] = i;
    36     ll ans = 0,k;
    37     
    38     for(int i = 1; i <= n; i ++){
    39         k = query(index[i]);
    40         ans += k*(n-i-index[i]+k+1);
    41         add(index[i]);
    42     }
    43     cout << ans << endl;
    44     return 0;
    45 }
  • 相关阅读:
    Jquery Plugin模版
    jquery之extend
    java反射技术实例
    java基础汇总
    Java学习路线
    java的一个爬虫
    Java深度理解——Java字节代码的操纵
    java编程思想-基础
    hdu 5201 The Monkey King【容斥原理+组合数学】
    容斥原理
  • 原文地址:https://www.cnblogs.com/xingkongyihao/p/7158639.html
Copyright © 2011-2022 走看看