树状数组

数组c[x]是存放【x-lowbit(x)+1,x】的区间的数和   , lowbit(x) = x&(-x)。         lowbit(4)=0,lowbit(6)=2

查询【0-x】区间的数和(或者其它):

ans = c[本身]+c[本身-lowbit]+c[x - x&(-x)]。。。。。。一直到[]内的值等于0结束

private static int sum(int x) {     //查询           查询0——x的区间的个数     表示返回的是等级几          查询作用是ans = c[本身]+c[本身-lowbit]+c[x - x&(-x)]。。。。。。一直到[]内的值等于0结束
		// TODO Auto-generated method stub
            int s=0;
	    while (x>0)
	    {
	        s+=c[x];
	        x -=x&(-x);             // x = x-lowbit(x)      把这里的每个值都加一个           lowbit(x) = x&(-x)    
	    }
	    return s;
    }

 

更新:

更新本身,然后更新x+lowbit(x)的区间,一直更新到最大值

private static void insert(int x) {     //更新            c[x]树状数组,c[x]存放x-lowbit(x)的区间的数和
		// TODO Auto-generated method stub
	    while (x<500002*2)                    //因为c[x]是存放x-lowbit(x)的区间的数和,后面的数会储存有前面的值,所以更新的时候,要更新到n的最大值			                             
	    {								   //更新本身,然后更新x+lowbit(x)的区间,一直更新到最大值
	        c[x]++;
	        x+=x&(-x);                    // x = x+lowbit(x)  把这里的每个值都更新一下
	    }
	}

附上一题:

Gdufe_2018_Summer III (G)

                                                                           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

题解:求逆序数。

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {
	static InputReader scan = new InputReader(System.in);
	static int[] c = new int[500002*2];
	static int x1,y,n;
	static class InputReader {
		public BufferedReader reader;
		public StringTokenizer tokenizer;
		public InputReader(InputStream stream) {
			reader = new BufferedReader(new InputStreamReader(stream), 32768);
			tokenizer = new StringTokenizer("");
		}
		private void eat(String s) {
			tokenizer = new StringTokenizer(s);
		}
		public String nextLine() {
			try {return reader.readLine();
			} catch (Exception e) {return null;
			}
		}
		public boolean hasNext() {
			while (!tokenizer.hasMoreTokens()) {
				String s = nextLine();
				if (s == null)return false;
				eat(s);
			}
			return true;
		}
		public String next() {
			hasNext();
			return tokenizer.nextToken();
		}
		public int nextInt() {
			return Integer.parseInt(next());
		}
		public long nextLong() {
			return Long.parseLong(next());
		}
		public double nextDouble() {
			return Double.parseDouble(next());
		}
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		while(scan.hasNext()){
			n = scan.nextInt();
			if(n==0)
				break;
			Arrays.fill(c,0);
			long answer = 0;
			for(int i=1;i<=n;i++){
				x1 = scan.nextInt();
				x1++;
				answer += i-sum(x1)-1;
				insert(x1);
			}
			System.out.println(answer);
		}
	}
	private static void insert(int x) {     //更新            c[x]树状数组,c[x]存放x-lowbit(x)的区间的数和
		// TODO Auto-generated method stub
		while (x<500002*2)                    //因为c[x]是存放x-lowbit(x)的区间的数和,后面的数会储存有前面的值,所以更新的时候,要更新到n的最大值			                             
	    {								   //更新本身,然后更新x+lowbit(x)的区间,一直更新到最大值
	        c[x]++;
	        x+=x&(-x);                    // x = x+lowbit(x)  把这里的每个值都更新一下
	    }
	}
	private static int sum(int x) {     //查询           查询0——x的区间的个数     表示返回的是等级几          查询作用是ans = c[本身]+c[本身-lowbit]+c[x - x&(-x)]。。。。。。一直到[]内的值等于0结束
		// TODO Auto-generated method stub
		int s=0;
	    while (x>0)
	    {
	        s+=c[x];
	        x -=x&(-x);             // x = x-lowbit(x)      把这里的每个值都加一个           lowbit(x) = x&(-x)    
	    }
	    return s;
	}

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值