hdu1394逆序数(线段树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394
题目大意:逆序数:即假设在数组a中,假如i<j,但是a[i]>a[j]。
现在有一个数组,含有n个数(为0-(n-1)的一个排列),依次把第一个数,放到数组最后面,求其中逆序数数目最小是多少?
例:
解题思路:首先,我们要思考对于一个数组怎样求出它的逆序数的总个数,这里有两种方法,最简单的是,直接暴力,两层循环就可以搞定。这里主要讲一下第二种方法,用线段树也可以很巧妙的求它的逆序数个数,我们先建立一颗空树,然后一个一个将节点插入树中,我们把数组中数的大小看成在树中的位置,然后每插入一个节点,就统计大于这个数的数目,即产生的逆序数的数目,然后再更新该位置的数值为1.这样就求出了初始状态下的逆序数sum了。
然后要求出最小的逆序数,因为数组是0到n-1的一个排列,所以如果当你把第一个数从第一个放到最后一个的时候,逆序数就会减少a【i】个,同时增加n-(a[i]+1)个。所以我们只需要枚举依次把第一个数放到最后位置,所产生的逆序数sum+(n-2*num[i]-1)取最小值即可。
附上代码:
暴力解法:
#include<iostream>
using namespace std;
#define inf 0x3f3f3f3f
int n,a[]; int main()
{
while(~scanf("%d",&n))
{
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
int sum=;
for(int i=;i<=n;i++)
{
for(int j=i+;j<=n;j++)
{
if(a[i]>a[j])
sum++;
}
}
int ans=inf;
for(int i=;i<=n;i++)
{
sum+=(n-*a[i]-);
ans=min(ans,sum);
}
printf("%d\n",ans);
}
return ;
}
线段树解法:
#include<iostream>
#include<cstring>
using namespace std;
#define ll long long
#define maxn 10005
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define pushup() tree[root]=tree[root<<1]+tree[root<<1|1]
int n,tree[maxn<<],num[maxn<<]; /*
void pushdown(int l,int r,int root)
{
if(add[root])
{
add[root<<1]+=add[root];
add[root<<1|1]+=add[root];
tree[root<<1]+=l*add[root];
tree[root<<1|1]+=r*add[root];
add[root]=0;
}
}
void build(int l,int r,int root)
{
add[root]=0;
if(l==r)
{
tree[root]=num[tot++];
return;
}
int mid=l+r>>1;
build(lson);
build(rson);
pushup();
}*/
void update(int pos,int val,int l,int r,int root)
{
if(l==r)
{
tree[root]=val;
return;
}
int mid=l+r>>;
if(pos<=mid)
update(pos,val,lson);
else
update(pos,val,rson);
pushup();
}
int query(int L,int R,int l,int r,int root)
{
if(L<=l&&R>=r)
return tree[root];
int ans=,mid=l+r>>;
if(L<=mid)
ans+=query(L,R,lson);
if(R>mid)
ans+=query(L,R,rson);
return ans;
} int main()
{
while(~scanf("%d",&n))
{
memset(tree,,sizeof(tree));//初始时,为空树,直接memset
int sum=;
for(int i=;i<=n;i++)
{
scanf("%d",&num[i]);
sum+=query(num[i]+,n,,n,);
update(num[i]+,,,n,);
}
int ans=sum;
for(int i=;i<=n;i++)
{
sum+=(n-*num[i]-);
ans=min(ans,sum);
}
printf("%d\n",ans);
}
return ;
}
hdu1394逆序数(线段树)的更多相关文章
- HDU 1394 Minimum Inversion Number(最小逆序数 线段树)
Minimum Inversion Number [题目链接]Minimum Inversion Number [题目类型]最小逆序数 线段树 &题意: 求一个数列经过n次变换得到的数列其中的 ...
- HDU 1394 逆序数 线段树单点跟新 | 暴力
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
- 51Nod 1019 逆序数(线段树)
题目链接:逆序数 模板题. #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a) ...
- POJ 2299 Ultra-QuickSort 求逆序数 线段树或树状数组 离散化
我用的线段树写的. num数组表示已插入的数值的个数. 由于a[i]数值很大,但是n不是很大,所以要离散化处理 9 1 0 5 4 离散化后 4 1 0 3 2 这样保证最大值不会超过n #inclu ...
- hdu1394 分治 or 线段树
利用分治求一次逆序数,然后每次把第一个元素放到末尾,设该交换元素的值为x,设上一次求得的逆序数为y,那么此时的逆序数等于y - x + (n - x - 1),减去x是因为x作为第一个元素,其后共有x ...
- 逆序对 线段树&树状数组 (重制版)
逆序对的定义:长度为n的数组a,求满足i<j时a[i]>a[j]条件的数对个数. 第一次接触这种问题的人可能是更先想到的是n^2去暴力数前面有几个比他大的数. int main() { i ...
- 51nod1019逆序数(归并排序/树状数组)
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1019 题意:中文题诶- 思路: 方法1:归并排序- 归并排序过 ...
- 2019.01.22 bzoj3333: 排队计划(逆序对+线段树)
传送门 题意简述:给出一个序列,支持把ppp~nnn中所有小于等于apa_pap的'扯出来排序之后再放回去,要求动态维护全局逆序对. 思路:我们令fif_ifi表示第iii个位置之后比它大的数的个 ...
- CF #301 E:Infinite Inversions(逆序数,树状数组)
A-Combination Lock B-School Marks C-Ice Cave D-Bad Luck Island E-Infinite Inversions E:Infini ...
随机推荐
- C#设计模式之3:观察者模式
C#中已经实现了观察者模式,那就是事件,事件封装了委托,使得委托的封装性更好,在类的内部定义事件,然后在客户端对事件进行注册: public class Subject { public event ...
- C#设计模式之2:单例模式
在程序的设计过程中很多时候系统会要求对于某个类型在一个应用程序域中只出现一次,或者是因为性能的考虑,或者是由于逻辑的要求,总之是有这样的需求的存在,那在设计模式中正好有这么一种模式可以来满足这样的要求 ...
- gulp项目和webpack项目在浏览器中查看的方式
在存在.git的目录下,按住shift+左键,打开命令行或者使用git Bash Gulp: 输入gulp dev 本地起一个服务器,在项目中找到gulp.js,然后找本地服务器,找到host和por ...
- Java 异常处理的误区和经验总结
Java 异常处理的误区和经验总结 1 本文着重介绍了 Java 异常选择和使用中的一些误区,希望各位读者能够熟练掌握异常处理的一些注意点和原则,注意总结和归纳.只有处理好了异常,才能提升开发人员 ...
- 高并发之API接口限流
在开发高并发系统时有三把利器用来保护系统:缓存.降级和限流 缓存 缓存的目的是提升系统访问速度和增大系统处理容量 降级 降级是当服务出现问题或者影响到核心流程时,需要暂时屏蔽掉,待高峰或者问题解决后再 ...
- mktemp -t -d用法
mktemp命令用于建立暂存文件或者文件夹,帮助文档如下: Usage: mktemp [OPTION]... [TEMPLATE] Create a temporary file or direct ...
- fiddler 学习笔记1-下载安装、开启、关闭抓包功能
1 下载安装(安装于C盘之外的空间中) https://www.telerik.com/fiddler 2 开启抓包功能:安装后默认为开启状态 点击 file-capture 或左下角capture ...
- FormDestroy 和 FormClose 有什么区别和联系?
1.窗口的所有资源真正释放时调用 FormDestroy.当你关闭窗口时,VCL会调用FormClose,如果你在FormClose里写Action = caFree,那么VCL会继续调用FormDe ...
- Windows 10 安装PHP Manager 失败的解决办法
首先安装.NET 2.0和.NET 3.5, 在 控制面板----程序----启用或关闭Windows功能 里面 然后修改注册表:HKLM/System/CCS/Services/W3SVC/P ...
- 在线制作css动画——CSS animate
熟悉CSS的人都知道,CSS可以实现很多漂亮的动画,特别是它的在线功能,能够帮助人们解决很多制作动画的效果.今天特别推荐一个在线CSS插件功能——cssanimate,这个最大的特色就是以图形界面方式 ...