OJ-Problems-Source/HDOJ/1394.cpp
2016-08-17 11:57:18 +08:00

138 lines
3.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/// HDU 1394
/// General includes
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
///求数列逆序数
inline int GetInversionNumberOfSequence(int* seq,int len)
{
int ans=0;
for(int i=0;i<len-1;i++)
{
for(int j=i;j<len;j++)
{
if(seq[i]>seq[j])ans++;
}
}
return ans;
}
/// 最基础的线段树: 单点更新,区间运算(求和)
namespace SegmentTree
{
const int MAXN = 1000100;
const int MAXTREENODE = MAXN<<2;
struct node
{
int lt,rt;
int val;
};
node tree[MAXTREENODE];
/// _internal_v is a indexer of SegmentTree. It guides the procedure to the right node.
void build(int L,int R,int _internal_v=1) /// Build a tree, _internal_v is 1 by default.
{
tree[_internal_v].lt=L;
tree[_internal_v].rt=R;
if(L==R)
{
///scanf("%d",&tree[_internal_v].val);
tree[_internal_v].val = 0;
return;
}
int mid=(L+R)>>1;
build(L,mid,_internal_v<<1);
build(mid+1,R,_internal_v<<1|1);/// x<<1 == x*2; x<<1|1 == x*2+1; (faster == slower)
/// SegmentTree Main Algorithm
tree[_internal_v].val=tree[_internal_v<<1].val+tree[_internal_v<<1|1].val;
}
void update(int Pos,int _internal_v=1)/// Update a position, _internal_v is 1 by default.
{
if(tree[_internal_v].lt==tree[_internal_v].rt)
{
tree[_internal_v].val=1;
return;
}
/// Update Deep-Loop
if(Pos <= tree[_internal_v<<1].rt) update(Pos,_internal_v<<1);
if(Pos >= tree[_internal_v<<1|1].lt) update(Pos,_internal_v<<1|1);
/// SegmentTree Main Algorithm
tree[_internal_v].val = tree[_internal_v<<1].val+tree[_internal_v<<1|1].val;
}
int _internal_ans;
inline void _internal_clear_ans()
{
_internal_ans=0;
}
inline int _internal_get_ans()
{
return _internal_ans;
}
void basic_query(int L,int R,int _internal_v=1)/// Query A Segment [L,R] , _internal_v is 1 by default.
{
if(tree[_internal_v].lt >= L && tree[_internal_v].rt <= R)
{
_internal_ans+=tree[_internal_v].val;
return;
}
if(L <= tree[_internal_v<<1].rt) basic_query(L,R,_internal_v<<1);
if(R >= tree[_internal_v<<1|1].lt) basic_query(L,R,_internal_v<<1|1);
}
int query(int L,int R)
{
_internal_clear_ans();
basic_query(L,R);
return _internal_get_ans();
}
}/// End of namespace SegmentTree
const int MAXN = 5005;
int a[MAXN];
int main()
{
using namespace SegmentTree;
int n;
while(scanf("%d",&n)==1)
{
build(1,n);
int TSum=0;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
//a[i]+=1; /// From 0 to 1, ... From n-1 to n (Understand)
///Query ? Why ??
TSum+=query(a[i]+1,n);
update(a[i]+1);
}
int MinSum=TSum;
for(int i=0;i<n;i++)
{
/// 当a[i]由第一个变为最后一个时,
/// 要加上a[i]后面大于a[i]的数的个数,
/// 有n-1-a[i]个要减去a[i]后面小于a[i]的数的个数,
/// 有a[i]个注意i是从0开始的
TSum=TSum+n - 2*a[i] -1;
MinSum=min(MinSum,TSum);
}
printf("%d\n",MinSum);
}
return 0;
}