Advertisement

NYOJ 117 求逆序数 (树状数组 + 离散化思路)

阅读量:

求逆序数

时间限制: 2000 ms | 内存限制: 65535 KB

难度: 5

描述

在一个排列中任取两个元素,在其相对位置与其数值大小相反的情况下,则称这对元素为一个逆序;该排列中所有这样的有序对的数量即被定义为该排列的逆序总数

现在,给你一个N个元素的序列,请你判断出它的逆序数是多少。

比如 1 3 2 的逆序数就是1。

请用户输入一个整数值T作为测试数据组的数量(1到5之间)。对于每个测试用例而言,在每一行中将有一个整数值N来标识该序列包含的具体元素数量(2到一百万之间)。在接下来的一行中将会有正好N个整数值Ai(其中每个Ai满足条件:小于十亿),这些数值构成了整个序列的所有元素。

数据保证在多组测试数据中,多于10万个数的测试数据最多只有一组。

输出 输出该数列的逆序数

样例输入

复制代码

样例输出

复制代码

为了实现将数值映射至相应位置的任务,
为了解决数值过于分散且规模较大的问题,
我们可以采取以下步骤:
首先,
将每个数值及其对应的位置信息存储于结构体数组中;
接着,
按数值大小进行排序;
然后,
采用连续整数序列1,2,3,…依次替代原有数值;
最后,
随后将reflect数组以逆序方式插入到树状数组中;
每一步骤完成后,
计算当前插入点之前所有已存在的节点之和,
这一步骤等价于求取当前节点在已处理节点中所处的位置排名,
从而得到该节点在整个序列中的逆序数目。

代码如下:


复制代码
  #include<cstdio>

    
 #include<iostream>
    
 #include<cstring>
    
 #include<algorithm>
    
 using namespace std;
    
 int tree[1000005];
    
 int reflect[1000005];
    
 int n;
    
 struct node
    
 {
    
 	int val;
    
 	int pos;
    
 }a[1000005];
    
 bool cmp(node n1, node n2)
    
 {
    
 	if(n1.val != n2.val)
    
 	return n1.val < n2.val;
    
 	return n1.pos < n2.pos;
    
 }
    
 void add(int k, int num)
    
 {
    
 	while(k <= n)
    
 	{
    
 		tree[k] += num;
    
 		k += k & -k;
    
 	}
    
 }
    
 long long query(int k)
    
 {
    
 	int sum = 0;
    
 	while(k >= 1)
    
 	{
    
 		sum += tree[k];
    
 		k -= k & -k;
    
 	}
    
 	return sum;
    
 }
    
 int main()
    
 {
    
 	int T, i, j;
    
 	long long sum;
    
 	cin >> T;
    
 	while(T --)
    
 	{
    
 		cin >> n;
    
 		sum = 0;
    
 		memset(tree, 0, sizeof(tree));
    
 		for(i = 1; i <= n; i++)
    
 		{
    
 			scanf("%d", &a[i].val);
    
 			a[i].pos = i;
    
 		}
    
 		sort(a + 1, a + n + 1, cmp);//离散化,将数组按值从小到大排列 
    
 		for(i = 1; i <= n; i++)
    
 		{
    
 			reflect[i] = a[i].pos;//映射数组,从值到位置的映射 
    
 		}
    
 		for(i = n; i >= 1; i--)//将数从大到小添加,每添加一个数,求该数前面有多少个数, 
    
 		{
    
 			add(reflect[i], 1);
    
 			sum += query(reflect[i]) - 1;//-1是除去该数本身 
    
 		}
    
 		cout << sum <<endl;
    
 	}
    
 	return 0;
    
 }

全部评论 (0)

还没有任何评论哟~