hdu 1394——Minimum Inversion Number

线段树

//31MS 340K c++
#include<iostream>
#include<cstdio>
using namespace std;
#define maxn 5010
#define ls (rt<<1)
#define rs (rt<<1|1)
#define mid ((t[rt].l+t[rt].r)>>1)
struct tree
{
	int l,r;
	int sum;
}t[maxn<<4];
int num[maxn];
void pushup(int rt)
{
	t[rt].sum=t[ls].sum+t[rs].sum;
}
void build(int rt,int l,int r)
{
	t[rt].l=l,t[rt].r=r,t[rt].sum=0;
	if(l==r)
		return ;
	build(ls,l,mid);
	build(rs,mid+1,r);
}
void add(int rt,int x)
{
	if(t[rt].l==t[rt].r)
	{
		t[rt].sum=1;
		return ;
	}
	if(x<=mid)
		add(ls,x);
	else
		add(rs,x);
	pushup(rt);
}
int query(int rt,int l,int r)
{
	if(t[rt].l==l&&t[rt].r==r)
		return t[rt].sum;
	if(r<=mid)
		return query(ls,l,r);
	else
		if(l>mid)
			return query(rs,l,r);
		else
			return query(ls,l,mid)+query(rs,mid+1,r);
}
int main()
{
	int n;
	while(~scanf("%d",&n))
	{
		build(1,0,n-1);
		int sum=0;
		for(int i=0;i<n;i++)
		{
			scanf("%d",&num[i]);
			sum+=query(1,num[i],n-1);
			add(1,num[i]);		
		}
			
		int ans=sum;
		for(int i=0;i<n-1;i++)
		{
			sum+=n-1-2*num[i];
			ans=min(ans,sum);
		}	
		printf("%d\n",ans);
	}
	return 0;
}


 

树状数组

//15MS 308K  c++
#include<cstdio>
#include<iostream>
using namespace std;
#define maxn 5010
int num[maxn];
int t[maxn];
int n;
int lowbit(int x)
{
	return (-x)&x;
}
int Sum(int x)
{
	int sum=0;
	while(x>=1)	
	{
		sum+=t[x];
		x-=lowbit(x);
	}
	return sum;
}
void Update(int x)
{
	while(x<=n)
	{
		t[x]++;
		x+=lowbit(x);
	}
}
int main()
{
	while(~scanf("%d",&n))
	{
		memset(t,0,sizeof(t));
		int sum=0;
		for(int i=0;i<n;i++)
		{
			scanf("%d",&num[i]);
			sum+=Sum(n)-Sum(num[i]+1);
			Update(num[i]+1);
		}
		int ans=sum;
		for(int i=0;i<n-1;i++)
		{
			sum+=n-1-2*num[i];
			ans=min(sum,ans);
		}
		printf("%d\n",ans);
	}
	return 0;
}



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值