数组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;
}
}