hdu2838Cow Sorting(树状数组+逆序数)
Posted slgkaifa
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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(树状数组+逆序数)的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ1697: [Usaco2007 Feb]Cow Sorting牛排序
Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Cards Sorting(树状数组)