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); } }