线段树---HDU1394Minimum Inversion Number
此题和上题略有不同,但是大体差不多,不过要把题意转换过来,题目大体意思为, 输入n, 也就是n个数,这些数为0 - (n-1), 这些数刚开始给定输入的顺序, 然后求他的逆序数,然后接着把第一个移到这个数列的末尾,这时候再求出一个逆序数,直到移动一个周期,也就是移动了n次, 求他们之中的最小的一个逆序数。
大体思路:
1. 首先建立线段树,初始化每个节点的值都为0
2. 输入原序列的同时,将原序列的逆序数求出来
其中这个求的过程为找到它导致的逆序数为多少,就是找在它之前有多少个比它大的
3. 遍历一遍, 然后将剩下的n - 1 个序列的逆序数求出来,其中这里有个公式, 可以推导出来,就是可以这么考虑,假设这是第一次将第一个数移到数组的末尾,假设这个数为X[i], 它所导致的 整个数组的逆序数的变化为: 首先,它造成他后面数的逆序数为X[i](这里的X[i]就是它本身), 这个是当前数组中把它去掉之后减少的逆序数, 所以去掉它之后整个数组的逆序数就是 Sum - x[i](这里Sum就是总的逆序数), 然后把它加到最后,它可以增加的逆序数就为 n - 1 - x[i], 所以变化这一次当前数组的逆序数为 Sum - x[i] + n - 1 - x[i]; 这个可以这么求公式,是因 为这个题特殊, 因为数组里面的数为从0 - n-1, 而且还没有重复的。
下面是代码的实现:
- #include <cstdio>
- #include <algorithm>
- using namespace std;
- const int MAX = * ;
- int sum[MAX];
- //更新跟其有关的以上所有节点
- void pushUp(int root)
- {
- sum[root] = sum[root * ] + sum[root * + ];
- }
- void buildTree(int root, int left, int right)
- {
- sum[root] = ;//初始化
- if(left == right)
- {
- return;
- }
- int mid = (left + right) / ;
- buildTree(root * , left, mid);
- buildTree(root * + , mid + , right);
- //pushUp(root);//这里可以不需要, 因为初始化都是0
- }
- void update(int root, int pos, int left, int right)
- {
- if(left == right)
- {
- sum[root]++;
- return;
- }
- int mid = (left + right) / ;
- if(pos <= mid)
- update(root * , pos, left, mid);
- else
- update(root * + , pos, mid + , right);
- pushUp(root);
- }
- //L, R代表要寻找的区间, left和right代表当前区间
- int getSum(int root, int L, int R, int left, int right)
- {
- /*找大于L的, 因为大于L才能导致逆序数, 所以找它之前所有大于L的,
- 即在线段上区间可以这么写 */
- if(L <= left && R >= right)
- {
- return sum[root];
- }
- int mid = (left + right) / ;
- int res = ;
- if(L <= mid)
- {
- res += getSum(root * , L, R, left, mid);
- }
- if(R > mid)
- {
- res += getSum(root * + , L, R, mid + , right);
- }
- return res;
- }
- int main()
- {
- int x[MAX];
- int n;
- while(~scanf("%d", &n))
- {
- buildTree(, , n - );
- int Sum = ;
- for(int i = ; i < n; i++)
- {
- scanf("%d", &x[i]);
- //获得当前数导致的逆序数
- Sum += getSum(, x[i], n - , , n - );
- update(, x[i], , n - );
- }
- int t = Sum;
- for(int i = ; i < n; i++)
- {
- //此公式是由 Sum = Sum - x[i] + n - 1 - x[i]的变形
- Sum += n - x[i] - x[i] - ;
- t = min(Sum, t);
- }
- printf("%d\n", t);
- }
- return ;
- }
线段树---HDU1394Minimum Inversion Number的更多相关文章
- hdu1394--Minimum Inversion Number(线段树求逆序数,纯为练习)
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Ot ...
- hdu1394Minimum Inversion Number(线段树,求最小逆序数)
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
- hdu1394Minimum Inversion Number
Problem Description The inversion number of a given number sequence a1, a2, ..., an is the number of ...
- HDU1394-Minimum Inversion Number
http://acm.hdu.edu.cn/showproblem.php?pid=1394 Minimum Inversion Number Time Limit: 2000/1000 MS (Ja ...
- C++-HDU1394-Minimum Inversion Number[数据结构][树状数组]
给出0~n-1的一个排列,可以整体移动,求逆序对最小值 把数字num[i]的加入,等价于树状数组的第n-num[i]位加1 因为num[i]是第 (n-1)-num[i]+1=n-num[i]大的数字 ...
- 线段树总结 (转载 里面有扫描线类 还有NotOnlySuccess线段树大神的地址)
转载自:http://blog.csdn.net/shiqi_614/article/details/8228102 之前做了些线段树相关的题目,开学一段时间后,想着把它整理下,完成了大牛NotOnl ...
- HDU 1394 Minimum Inversion Number(最小逆序数 线段树)
Minimum Inversion Number [题目链接]Minimum Inversion Number [题目类型]最小逆序数 线段树 &题意: 求一个数列经过n次变换得到的数列其中的 ...
- HDU 1394 Minimum Inversion Number(最小逆序数/暴力 线段树 树状数组 归并排序)
题目链接: 传送门 Minimum Inversion Number Time Limit: 1000MS Memory Limit: 32768 K Description The inve ...
- ACM Minimum Inversion Number 解题报告 -线段树
C - Minimum Inversion Number Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d &a ...
随机推荐
- JavaScript 目标装配式编程(Target Assemble Programming)
TAP概述 脚本中一切皆对象,若还以传统模式思考编程模式,那简直是对不起脚本解释器的强大支持:我们应该以最接近人类操作方式的来表达人的意图. 更接近工作实践的方式,比如游戏中,一个人物一个角色,人物的 ...
- c语言中3n+1溢出问题解决
3n+1问题是一个简单有趣而又没有解决的数学问题.这个问题是由L. Collatz在1937年提出的.克拉兹问题(Collatz problem)也被叫做hailstone问题.3n+1问题.Hass ...
- jQuery截取字符串插件区分中英文
jQuery截取字符串插件区分中英文:截取字符串功能在大量网站都有应用,比如新闻列表这样的功能,因为新闻的标题长途未必都是恰如其分的,所以要根据需要截取指定长度的字符串,下面就分享一个jQuery实现 ...
- 无法为数据库 XXX 中的对象XXX 分配空间,因为 'PRIMARY' 文件组已满。请删除不需要的文件、删除文件组中的对象、将其他文件添加到文件组或为文件组中的现有文件启用自动增长,以便增加可用磁盘空间。
无法为数据库 XXX 中的对象XXX 分配空间,因为 'PRIMARY' 文件组已满.请删除不需要的文件.删除文件组中的对象.将其他文件添加到文件组或为文件组中的现有文件启用自动增长,以便增加可用磁盘 ...
- html中插入flash代码详解(转载)
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://down ...
- IOS开发----委托机制
委托模式从GoF装饰模式.适配器模式和模板方法等演变过来,几乎每一个应用都会或多或少的用到委托模式. 在古希腊有一个哲学家,他毕生只做三件事情:“睡觉”.“吃饭”.和“工作”.为了更好的生活,提高工作 ...
- Codeforces Round #313 A Currency System in Geraldion
A Currency System in Geraldion Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64 ...
- 转:Java开发牛人十大必备网站
原文来自于:http://www.importnew.com/7980.html 以下是我收集的Java开发牛人必备的网站.这些网站可以提供信息,以及一些很棒的讲座, 还能解答一般问题.面试问题等.质 ...
- Xamarin.Forms WebView
目前本地或网络的网页内容和文件加载 WebView是在您的应用程序显示Web和HTML内容的视图.不像OpenUri,这需要用户在Web浏览器的设备上,WebView中显示您的应用程序内的HTML内容 ...
- BZOJ 1027 [JSOI2007]合金
1027: [JSOI2007]合金 Time Limit: 4 Sec Memory Limit: 162 MBSubmit: 2605 Solved: 692[Submit][Status][ ...