• 树形数组 java


    2^k求法

    int lowbit(int x)
    {
         return x&(-x);    
    }

    lowbit()的返回值就是 2^k 次方的值。

    基本树形数组的模板

    import java.util.*;
        public class Main1{
            static int N=10010;
            static int n,x,ans;
            static int c[] = new int [N];
            static int a[] = new int [N];
            public static int sum(int n){
                int sum=0;
                while(n>0){
                    sum+=c[n];
                    n-=n&(-n);
                }
                return sum;
            }
            public static void add(int i ,int x,int n){
                while(i<=n){
                    c[i]+=x;
                    i+=i&(-i);
                }
            }
            public static void main(String[] args) {
                Scanner sc = new Scanner(System.in);
                int n = sc.nextInt();
                for(int i=1;i<=n;i++){
                    a[i]= sc.nextInt();
                    add(i,a[i],n);
                }
                ans=sum(n);
                System.out.println(ans);
            }
        }

    例题:

    hihocoder1524

    树形数组求逆序对,用树形数组可以快速统计出ai>aj对的数量,时间复杂度可以很好的提升,先感慨一个大小为a的最大值的数组c,每当读入一个数时,我们可以用桶排序思想,将c[a[i]]加1,然后我们 统计c[1]~c[a[i]]

    的和,ans-1(除去这个数本身)就是在这个数前面有多少个数比它小,我们只需要用i-ans就可以计算出前面有多少个数比他大,也就是逆序对的数量

        给定一个1-N的排列A1, A2, ... AN,如果Ai和Aj满足i < j且Ai > Aj,我们就称(Ai, Aj)是一个逆序对。  
    
        求A1, A2 ... AN中所有逆序对的数目。  
    public class Main1{
        static int N = 10010;
        static int n,x,ans=0;
        
        static int c[]= new int [N];
        public static int sum(int n){
            int sum=0;
            while(n>0){
                sum+=c[n];
                n-=n&(-n);
            }
            return sum;
        }
        public static void add(int i,int x){
            while(i<=n){
                c[i]+=x;
                i+=i&(-i);
            }
        }
        public static void main(String[] args) {
                Scanner sc=new Scanner(System.in);
                n = sc.nextInt();
                for(int i=1;i<=n;i++){
                    x=sc.nextInt();
                    add(x,1);
                    ans+=(i-sum(x));
                    
                }
             System.out.println(ans);
        
            }
    }
  • 相关阅读:
    『Linux学习笔记』0. 在Windows中运行Linux内核(Ubuntu)
    『Linux学习笔记』10. 文本编辑器
    『Linux学习笔记』9. 进程
    九种乱码解决办法(非原创)
    Eclipse中10个最有用的快捷键组合
    MVC(Model View Controller)框架
    ognl表达式
    统计一段文字中数组、中文、英文字母、空格以及其他特殊字符出现的次数
    java基础知识4
    java基础知识3
  • 原文地址:https://www.cnblogs.com/ls-pankong/p/10504723.html
Copyright © 2020-2023  润新知