博客
关于我
2018HDU多校2-1010-Swaps and Inversions(hdu 6318)-逆序数,树状数组
阅读量:281 次
发布时间:2019-03-01

本文共 1373 字,大约阅读时间需要 4 分钟。

这里写图片描述

题意:

给出一个数列,其中每有一个逆序数就花费x元,也可以花费y元交换相邻两个数,求处理这个数列的最小花费

思路:

可分析出,交换一次最多只能减少一个逆序数,所以只可能全部交换或者一个都不交换,故此题只需求出逆序数个数即可

O(nlogn)时间下求逆序数个数,可用归并排序法或树状数组法
使用树状数组求解,先将数列从大到小排序,每次选取最大的数放入,树状数组中记录某位置出现数的个数(某位置是否有数),因选取的是最大的数,若最大数位置之前的位置有其他数的话,一定小于最大数,即有逆序数

代码:

#include 
#include
#include
using namespace std;const int N=100050;int n;long long c[N]; //c[n]表示a[1~n]的和,a数组省略struct node{ int val,pos;}a[100005];int lowbit(int x) //求2^k{ return x & -x;}long long getsum(int n) //区间查询,求a[1~n]的和{ long long res = 0; while(n>0) { res+=c[n]; n=n-lowbit(n); } return res;}int change(int x) //单点更新,将c[x]的值加1{ while(x<=n) { c[x]++; x+=lowbit(x); }}bool cmp(node a,node b) //包含相同数{ if(a.val!=b.val) return a.val>b.val; return a.pos>b.pos;}int main(){ std::ios::sync_with_stdio(false); int x,y; while(cin>>n>>x>>y) { memset(c,0,sizeof(c)); for(int i=1;i<=n;i++) { cin>>a[i].val; a[i].pos=i; } sort(a+1,a+n+1,cmp); long long cnt=0; for(int i=1;i<=n;i++) { change(a[i].pos); //修改最大数位置的值 cnt+=getsum(a[i].pos-1); //最大数位置之前的所有位置和,即区间求和,可知比当前数小的数有多少个 } long long ans1=cnt*x; long long ans2=cnt*y; cout<
<
你可能感兴趣的文章
Nginx反向代理配置
查看>>
Nginx启动SSL功能,并进行功能优化,你看这个就足够了
查看>>
nginx启动脚本
查看>>
Nginx在Windows上和Linux上(Docker启动)分别配置基本身份认证示例
查看>>
Nginx在Windows下载安装启动与配置前后端请求代理
查看>>
Nginx多域名,多证书,多服务配置,实用版
查看>>
nginx如何实现图片防盗链
查看>>
Nginx学习总结(12)——Nginx各项配置总结
查看>>
Nginx学习总结(13)——Nginx 重要知识点回顾
查看>>
Nginx学习总结(14)——Nginx配置参数详细说明与整理
查看>>
nginx学习笔记002---Nginx代理配置_案例1_实现了对前端代码的方向代理_并且配置了后端api接口的访问地址
查看>>
Nginx安装与常见命令
查看>>
Nginx安装及配置详解
查看>>
nginx安装配置
查看>>
Nginx实战经验分享:从小白到专家的成长历程!
查看>>
Nginx实现反向代理负载均衡
查看>>
nginx实现负载均衡
查看>>
nginx常用命令及简单配置
查看>>
nginx开机启动脚本
查看>>
nginx异常:the “ssl“ parameter requires ngx_http_ssl_module in /usr/local/nginx/conf
查看>>