SOJ 2309: In the Army Now 树状数组求逆序对

原创 2014年10月01日 11:24:48
Time Limit:1000ms Memory Limit:32768KB

Description

The sergeant ordered that all the recruits stand in rows. The recruits have
formed K rows with N people in each, but failed to stand according to their
height. The right way to stand in a row is as following: the first soldier must
be the highest, the second must be the second highest and so on; the last soldier
in a row must be the shortest. In order to teach the young people how to form
rows, the sergeant ordered that each of the recruits jump as many times as there
are recruits before him in his row who are shorter than he. Note that there are
no two recruits of the same height.
The sergeant wants to find which of the rows will jump the greatest total number
of times in order to send this row to work in the kitchen. Help the sergeant to
find this row.

Input

The first line of the input contains two positive integers N and K (2 ≤ N ≤
10000, 1 ≤ K ≤ 20). The following K lines contain N integers each. The recruits
in each row are numbered according to their height (1 — the highest, N — the
shortest). Each line shows the order in which the recruits stand in the
corresponding row. The first integer in a line is the number of the first recruit
in a row and so on. Therefore a recruit jumps as many times as there are numbers
which are greater than his number in the line before this number.

Output

You should output the number of the row in which the total amount of jumps is the
greatest. If there are several rows with the maximal total amount of jumps you
should output the minimal of their numbers.

Sample Input

3 3
1 2 3
2 1 3
3 2 1
 
分析:此题即求每一行的逆序对 找出逆序对最少的那一行编号
求逆序对可以采用归并排序 但另外一种更简单快捷的方法是使用树状数组(二叉索引树)
树状数组用于修改单点值的范围求和
点修改和范围求和均为O(logn)
其修改操作是从前往后修改
其求和操作是从前往前求和
数组表示的意义是根据下标与二倍数的关系的连续和
每次插入一个数 计算已插在其前面的数的数量
利用modify插数 再使用sum求数量
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int maxN=10000;
const int maxK=20;
const int inf=0xcfcfcfcf;



int C[maxN+5];

int n,k;


inline int sum(int x)
{
	int ret=0;
	while(x>0)
	{
		ret+=C[x];
		x-=x&(-x);
	}
	return ret;
}

inline void modify(int x,int d)
{
	while(x<=n)
	{
		C[x]+=d;
		x+=x&(-x);
	}
}


int main()
{
	int i,j,num;
	int MaxSum,Mindex,temp;
	while(scanf("%d%d",&n,&k)==2)
	{	

		MaxSum=inf;
		Mindex=1;

		for (j=1;j<=k;j++)
		{
		
			memset(C,0,sizeof(C));
			num=0;
			for (i=0;i<n;i++)
			{
				scanf("%d",&temp);	
				modify(temp,1);
				num+=i-sum(temp);
			}
	
			if (num>MaxSum)
			{
				MaxSum=num;
				Mindex=j;
			}

		}
		printf("%d\n",Mindex);
	}



	return 0;
}

 
总结:
因为本题频繁使用各函数 所以利用inline可以减少部分时间
 

soj 2309: In the Army Now (树状数组求逆序数)

@(K ACMer)题意: 可以发现就是求逆序数最大的哪一行 分析: 树状数组,求逆序数是非常经典的用法,当然归并排序的思想也可以来求. 每次新来一个数x我们就add(x , 1);这样维护数...
  • jibancanyang
  • jibancanyang
  • 2015-11-01 16:27:40
  • 158

归并排序,树状数组 两种方法求逆序对

我们知道,求逆序对最典型的方法就是树状数组,但是还有一种方法就是Merge_sort(),即归并排序。 实际上归并排序的交换次数就是这个数组的逆序对个数,为什么呢? 我们可以这样考虑:...
  • ACM_10000h
  • ACM_10000h
  • 2015-08-24 21:42:22
  • 2266

树状数组应用之——求逆序对

这里说的很好,把求逆序的步骤说的很明白,我也是看完才懂的,之前自己想了很久就是不明白为什么可以用树状数组求逆序    转载: 树状数组,具体的说是 离散化+树状数组。这也是学习树状数组的第一题....
  • lth404391139
  • lth404391139
  • 2014-10-02 16:06:24
  • 1277

求逆序对 (树状数组版)

基本思想和线段树求解逆序数是一样的,前一篇《求逆序对 线段树版》也介绍过,先对输入数组离散,数组里的元素都不相同可以直接hash,存在相同的数话可以采用二分。 离散化后对于每个f[i],找到f[i]...
  • u013923947
  • u013923947
  • 2014-08-18 14:53:05
  • 765

树状数组求逆序对及离散化

树状数组求逆序对及离散化 逆序对指的是一个序列中有两个数ai和aj,iaj,即它们下标与数值的增减不一致,那么对于这个问题:求一个序列中逆序对的个数,该如何解决呢? 我最初接触到的方法是归并排序,...
  • qq_37666409
  • qq_37666409
  • 2017-08-26 22:59:15
  • 205

逆序对 - 树状数组求解 - 高级数据结构

树状数组是一种非常高级的数据结构,用于求解动态的区间和问题。静态的区间和可以用前缀和用O(n)的时间预处理,再以O(1)的时间单次求解。而树状数组,维护的就是动态的前缀和。也就是说,树状数组可以实现下...
  • WenDavidOI
  • WenDavidOI
  • 2016-02-15 19:37:11
  • 604

[离散化+树状数组]逆序对

看到这道题,我只能想到的思路是大暴力。。。我是蒟蒻。。去看了一下树状数组的介绍,还是半懂不懂,看了题解好长时间,才有点明白。树状数组传送门http://blog.csdn.net/int64ago/a...
  • jjqjinqiu
  • jjqjinqiu
  • 2016-05-01 12:27:31
  • 280

《树状数组求逆序对数》

#include #include #define maxn 1005 int tree[maxn]; int lowbit(int x) { return x&(-x); } void up...
  • a709743744
  • a709743744
  • 2015-12-09 09:22:14
  • 284

POJ:2299 Ultra-QuickSort(树状数组+离散化+技巧+求逆序对)

Ultra-QuickSort Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 55647   Accepted:...
  • zugofn
  • zugofn
  • 2016-08-17 10:34:25
  • 274

poj 3067(树状数组求逆序对)

题意:日本岛东海岸与西海岸分别有N和M个城市,现在修高速公路连接东西海岸的城市,求交点个数。 做法:记每条告诉公路为(x,y), 即东岸的第x个城市与西岸的第y个城市修一条路。当两条路有交点时,满足...
  • Weiguang_123
  • Weiguang_123
  • 2012-08-22 14:50:48
  • 3608
收藏助手
不良信息举报
您举报文章:SOJ 2309: In the Army Now 树状数组求逆序对
举报原因:
原因补充:

(最多只允许输入30个字)