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

来源:互联网 发布:作业调度算法 编辑:程序博客网 时间:2024/06/11 12:00
Time Limit:1000ms Memory Limit:32768KB

Description

The sergeant ordered that all the recruits stand in rows. The recruits haveformed K rows with N people in each, but failed to stand according to theirheight. The right way to stand in a row is as following: the first soldier mustbe the highest, the second must be the second highest and so on; the last soldierin a row must be the shortest. In order to teach the young people how to formrows, the sergeant ordered that each of the recruits jump as many times as thereare recruits before him in his row who are shorter than he. Note that there areno two recruits of the same height.The sergeant wants to find which of the rows will jump the greatest total numberof times in order to send this row to work in the kitchen. Help the sergeant tofind 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 recruitsin each row are numbered according to their height (1 — the highest, N — theshortest). Each line shows the order in which the recruits stand in thecorresponding row. The first integer in a line is the number of the first recruitin a row and so on. Therefore a recruit jumps as many times as there are numberswhich 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 thegreatest. If there are several rows with the maximal total amount of jumps youshould output the minimal of their numbers.

Sample Input

3 31 2 32 1 33 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可以减少部分时间
 
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 电视版本低不支持投屏怎么办 绝地求生刺激战场不支持机型怎么办 手机不支持微信运动怎么办 淘宝虚拟商品买家退货退款怎么办 虚拟品申请啦退货退款怎么办 淘宝充值话费没到账怎么办 淘宝全球购买到假货怎么办 车跑路上没油了怎么办 摩托车跑路上没油了怎么办 话费充了不到帐怎么办 网上代充被骗了怎么办 天猫买东西没积分怎么办 购物时不要天猫积分怎么办 618没有天猫积分怎么办 话费充错了号码怎么办? 微信被骗充话费怎么办 微信话费充多了怎么办 睫毛烫的太卷了怎么办 烫完睫毛太卷了怎么办 烫睫毛太卷了怎么办 用微信充话费充错了怎么办 微信给空号充话费了怎么办 微信充话费充错号码是空号怎么办 淘宝充流量不到账怎么办 微信退货不退款怎么办 京东话费交错号怎么办? 微信缴费错了怎么办 给手机充话费被退款怎么办 买到假货淘宝商家已关店怎么办 手机刷错系统了怎么办 苹果手机成砖了怎么办 苹果6p变砖头怎么办 苹果刷成石头了怎么办 苹果手机更新成了砖头怎么办 京东售后好慢怎么办 京东商品超过售后期怎么办 京东过了售后期怎么办 京东售后不处理怎么办 京东售后不让退货怎么办 天猫盒子遥控器丢了怎么办 淘宝店铺的客服不理人怎么办