您的位置:首页 > 其它

hdu 1394【Minimum Inversion Number】

2012-12-01 12:43 211 查看
线段树

假如考虑iValue[i],则要先将iValue[1]->iValue[i-1]放在线段树里面,计算每一段里面包含多少个已遍历值(iValue[1]->iValue[i-1]),然后查找iValue[i]+1->n的值有多少个,这样的话,就相当与在查找iValue[1]->iValue[i-1]有多少个值是在iValue[i]+1->n范围的。(这一题目也可以用树状数组做)

代码如下:

#include <iostream>

using namespace std;

struct node
{
int low,high;
int value;
}seg[10005];
int iValue[5005];
int ans_one;

void build_tree(int root,int low,int high)
{
seg[root].low = low;
seg[root].high = high;
seg[root].value = 0;
if(low == high)
{
return;
}

int mid = (low + high) >> 1;
build_tree(root*2,low,mid);
build_tree(root*2+1,mid+1,high);
}

void s_tree(int root,int low,int high)
{
if(low <= seg[root].low && high >= seg[root].high)
{
ans_one +=seg[root].value;
return;
}

int mid = (seg[root].low + seg[root].high) >> 1;
if(high <= mid)
{
s_tree(root*2,low,high);
}else if(low > mid)
{
s_tree(root*2+1,low,high);
}else
{
s_tree(root*2,low,mid);
s_tree(root*2+1,mid+1,high);
}
}

void s_update(int root,int sValue)
{
seg[root].value ++;
if(seg[root].low == seg[root].high)
{
return;
}
int mid = (seg[root].low + seg[root].high) >> 1;
if(mid >= sValue)
{
s_update(root*2,sValue);
}else
{
s_update(root*2+1,sValue);
}
}
int main()
{
int n;
while(cin >> n)
{
for(int i = 1;i <= n;i ++)
{
cin >> iValue[i];
iValue[i] ++;
}

build_tree(1,1,n);
ans_one = 0;
for(int i = 1;i <= n;i ++)
{
if(iValue[i] <= n-1) s_tree(1,iValue[i]+1,n);
s_update(1,iValue[i]);
}

int ans = -1;
for(int i = 2;i <= n;i ++)
{
ans_one += (n-iValue[i-1]) - (iValue[i-1] - 1);
if(ans == -1 || ans > ans_one)
{
ans = ans_one;
}
}
cout << ans << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: