首页 > 代码库 > hdu2838Cow Sorting(树状数组+逆序数)
hdu2838Cow Sorting(树状数组+逆序数)
题目链接:点击打开链接
题意描写叙述:给定一个长度为100000的数组,每一个元素范围在1~100000,且互不同样,交换当中的随意两个数须要花费的代价为两个数之和。
问怎样交换使数组有序。花费的代价最小?
解题思路:
1、显然我们知道,要使一个数组有序至少交换的次数(即必需要交换的次数)为数组中的逆序数
2、因为数组的长度比較大所以我们能够通过树状数组来统计结果
此处须要两个树状数组
第一个:记录小于等于某个值的元素的个数
第二个:记录小于等于某个值的元素的和
代码:
#include <cstdio> #include <cstring> #define MAXN 100010 using namespace std; int C[MAXN]; int lowbit(int x) { return x&(-x); } int sum(int pos) { int ret=0; while(pos>0) { ret+=C[pos]; pos-=lowbit(pos); } return ret; } void add(int pos,int v) { while(pos<=100000) { C[pos]+=v; pos+=lowbit(pos); } } long long Ct[MAXN]; long long sumt(int pos) { long long ret=0; while(pos>0) { ret+=Ct[pos]; pos-=lowbit(pos); } return ret; } void addt(int pos,int v) { while(pos<=100000) { Ct[pos]+=v; pos+=lowbit(pos); } } int main() { int n; while(scanf("%d",&n)!=EOF) { memset(C,0,sizeof(C)); memset(Ct,0,sizeof(Ct)); long long ans=0; int x; for(int i=0; i<n; ++i) { scanf("%d",&x); add(x,1); addt(x,x); ans+=((sum(100000)-sum(x))*(long long)x+sumt(100000)-sumt(x));///注意溢出问题 } printf("%I64d\n",ans); } return 0; }
hdu2838Cow Sorting(树状数组+逆序数)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。