树状数组 _ 求逆序数

时间:2022-07-25
本文章向大家介绍树状数组 _ 求逆序数,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

注: 本文只是记录 ,您将从上面学习不到任何知识,除了 代码

(废话)第一次接触到树状数组,感觉接触到了新世界,理解这个思想用了好长时间,终于弄明白了(似懂非懂)。

还有接触到了 离散化的思想, 逆序数 , 感觉数学这么有用

问题 A: 最少的交换

时间限制: 1 Sec 内存限制: 32 MB

提交: 157 解决: 47

[提交][状态][讨论版][命题人:外部导入]

题目描述

现在给你一个由n个互不相同的整数组成的序列,现在要求你任意交换相邻的两个数字,使序列成为升序序列,请问最少的交换次数是多少?

输入

输入包含多组测试数据。每组输入第一行是一个正整数n(n<500000),表示序列的长度,当n=0时。 接下来的n行,每行一个整数a[i](0<=a[i]<=999999999),表示序列中第i个元素。

输出

对于每组输入,输出使得所给序列升序的最少交换次数。

样例输入

5
9
1
0
5
4
3
1
2
3
0

样例输出

6
0
import java.util.Arrays;
import java.util.Scanner;

/**
 * 树状数组
 * @author Administrator
 *
 */

class Node implements Comparable<Node>{
    public int index;
    public int value;
    
    public Node(int index,int value){
        this.index = index;
        this.value = value;
    }
    
    @Override
    public int compareTo(Node n) {
        return this.value-n.value;
    }
    
}
public class TreeArrayDemo {
    
    private static int [] c ;
    private static int [] array = new int [500010];
    private static int maxn;
    private static Node [] nodes ;
    
    public static int lowbit(int x){
        return x&(-x);
    }

    public static int getSum(int x)
    {
        int sum  = 0 ;
        for(int i = x;i>0;i-=lowbit(i)){
            sum+=c[i];
        }
        return sum;
    }
    
    public static void update(int x,int val)
    {
        for(int i = x;i<=maxn;i+=lowbit(i)){
            c[i]+=val;
        }

        
    }
    
    
    
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        while (cin.hasNext()) {
            maxn = cin.nextInt();
            
            if(maxn == 0)
            {
                break;
            }
            nodes = new Node [500010];
            c = new int [500010];
            
            
            for(int i = 1;i<=maxn;i++){
                int index = i;
                int val = cin.nextInt();
                Node node = new Node(index, val);
                nodes[i] = node;
            }
            //给节点进行排序
            Arrays.sort(nodes, 1,maxn+1);
            
            //对数据进行离散化
            for(int i = 1;i<=maxn;i++){
                array[nodes[i].index] = i;
            }
            
            for(int i = 1;i<=maxn;i++){
                System.out.println(array[i]);
            }
            
            long answer = 0;
            for(int i = 1;i<=maxn;i++)
            {
                update(array[i], 1);
                int n = getSum(array[i]);
                answer+=i-n;
            }
            
            System.out.println(answer);
        }
        
        
    }
    
    
}