线段树求逆序对(hdu1394Minimum Inversion Number)
说实话,线段树求逆序对我理解了半天诶,不知是否有人像我一样。
对于每个数来说,只有和已经出现过的、比它大的数才能形成逆序对,那么在给定的数列中,每给一个数就向前找比它大的数。
样例:10
1 3 6 9 0 8 5 7 4 2
首先将数组清0,0~9(n-1=9):0 0 0 0 0 0 0 0 0 0
出现“1” ,且现在数组中没有比它大的数,逆序对数sum+0,0~9(n-1=9):0 1 0 0 0 0 0 0 0 0
出现“3” ,且现在数组中没有比它大的数,逆序对数sum+0,0~9(n-1=9):0 1 0 3 0 0 0 0 0 0
出现“6” ,且现在数组中没有比它大的数,逆序对数sum+0,0~9(n-1=9):0 1 0 3 0 0 6 0 0 0
出现“9” ,且现在数组中没有比它大的数,逆序对数sum+0,0~9(n-1=9):0 1 0 3 0 0 6 0 0 9
出现“0” ,0后有4个数,逆序对数sum+4,0~9(n-1=9):0 1 0 3 0 0 6 0 0 9
以此类推。在每次查找完后将这个数加入数列。
在把原数列找完后,要开始将第一个数挪到后面去,比这个数 x 小的有 x 个,比这个数大的有 n-1-x个,于是 sum += (n-1-x) - x 。
#include<stdio.h>
#include<algorithm>
using namespace std;
int n;
int tree[5001*4];
void pushup(int node)
{tree[node]=tree[node<<1]+tree[node<<1|1];return ;
}
void build(int l,int r,int node)
{tree[node]=0;//将数组清0if(l==r){return ;}int mid=(l+r)>>1;build(l,mid,node<<1);build(mid+1,r,node<<1|1);
}
void update(int x,int l,int r,int node)
{if(l==r){tree[node]++;//是这个数出现了,并不是赋值return ;}int mid=(l+r)>>1;if(x<=mid){update(x,l,mid,node<<1);}else{update(x,mid+1,r,node<<1|1);}pushup(node);
}
int query(int l,int r,int st,int en,int node)
{if(st>=l&&en<=r)return tree[node];int mid=(st+en)>>1;int ret=0; if(mid>=l)ret+=query(l,r,st,mid,node<<1);if(mid<r)ret+=query(l,r,mid+1,en,node<<1|1);return ret;
}
int num[50005];
int main()
{while(scanf("%d",&n)!=EOF){int ans=0;build(0,n-1,1);for(int i=0;i<n;i++){scanf("%d",&num[i]);ans+=query(num[i],n-1,0,n-1,1);//询问是否有比 num[i] 大的数update(num[i],0,n-1,1); //将 num[i] 更新}int ret=ans;for(int i=0;i<n;i++){ans+=n-num[i]-num[i]-1;ret=min(ret,ans);}printf("%d\n",ret);}
}
线段树求逆序对(hdu1394Minimum Inversion Number)相关推荐
- HDU 4911 http://acm.hdu.edu.cn/showproblem.php?pid=4911(线段树求逆序对)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4911 解题报告: 给出一个长度为n的序列,然后给出一个k,要你求最多做k次相邻的数字交换后,逆序数最少 ...
- CodeForces - 1417E XOR Inverse(字典树求逆序对+分治)
题目链接:点击查看 题目大意:给出一个长度为 n 的数列 a,现在要求选出一个 x,将 a 中的每个元素都异或之后得到一个新的数列 b,要求数列 b 的逆序对最小,问最小的逆序对是多少,x 该如何选择 ...
- 线段树求逆序数(单点更新)
题目:HDU1394 Minimum Inversion Number 若abcde...的逆序数为k,那么bcde...a的逆序数是多少?我们假设abcde...中小于a的个数为t , 那么大于a的 ...
- hdu5775 Bubble Sort(线段树求逆序数)
题目点我点我点我 题目大意:按照题目的冒泡排序求每个数在排序过程中到达最右边位置与最左边位置之差. 解题思路:实际可变成max(左边比它大的数的个数,右边比它小的数的个数),用线段树解决,先求出每个数 ...
- 用不同的姿势求逆序对(复习篇)
用不同的姿势求逆序对(复习篇) 文章目录 用不同的姿势求逆序对(复习篇) 前言 讲解 归并排序 树状数组 线段树 题目 思路 代码 归并排序求逆序对 树状数组求逆序对 线段树求逆序对 历届试题 小朋友 ...
- 吉首大学2019年程序设计竞赛(重现赛) 干物妹小埋(线段树求最长上升子序列)
链接:https://ac.nowcoder.com/acm/contest/992/B 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536 ...
- codevs1688 求逆序对(权值线段树)
1688 求逆序对 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 查看运行结果 题目描述 Description 给定一个序列a1,a2,-,an,如 ...
- szu 寒训第二天 树状数组 二维树状数组详解,以及树状数组扩展应用【求逆序对,以及动态第k小数】
树状数组(Binary Index Tree) 树状数组可以解决可以转化为前缀和问题的问题 这是一类用以解决动态前缀和的问题 (有点像线段树简版) 1.对于 a1 + a2 + a3 + - + an ...
- 树状数组求逆序对_区间和的个数(树状数组)
327. 区间和的个数 给定一个整数数组 nums,返回区间和在 [lower, upper] 之间的个数,包含 lower 和 upper. 区间和 S(i, j) 表示在 nums 中,位置从 i ...
最新文章
- 飞桨深度学习开源框架2.0抢先看:成熟完备的动态图开发模式
- 技术分享:逆向分析ATM分离器
- linux用户及用户组管理
- 霍夫曼树(最优二叉树)的实现
- 用vbs自动切换不同网段的IP
- java 3des加密_Java使用3DES加密解密的流程 - 3des加密解密详细解释
- php的yii框架配置,php配置yii框架_PHP教程
- 组态王历史记录用access_Access数据库与表在 组态王中使用.ppt
- k-java游戏下载,KEmulator(JAVA手机游戏模拟器)
- 商务与经济统计 第三章案例
- 又一场“人机大战”?来自AI open无情碾压!
- onhashchange事件--司徒正美
- Frank-wolfe算法多OD对matlab实现
- 使用Universal Image Loader- Image can't be decoded
- 跨境电商运营 | 如何利用Instagram进行电子商务营销
- codeforces 645F Cowslip Collections
- 微信小程序(uniapp)获取用户位置信息及选择位置
- speedoffice(PPT)怎么给文字加粗
- 站长工具大全,站长工具哪个好用,站长在线工具
- 波段选股王怎么在市场中利用头肩底实现杀跌
热门文章
- 我的世界pe服务器坐标怎么显示,我的世界手机版坐标怎么看 PE版没有MOD怎么查看坐标...
- [MSSQL2005]再看CTE
- 加州圣塔克拉拉大学计算机专业,圣塔克拉拉大学在美国排位
- ContextCapture Master 倾斜摄影测量实景三维建模技术
- 第7周编程题在线测试
- cesium绘制折线_polyline
- 多边形(polygon)
- 腾讯系互联网券商富途证券将赴美IPO,最高融资3亿美元...
- 利用javadoc制作API文档
- 免费在线云服务CAD编辑软件AutoCAD易