注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

东月之神

在单纯的观念里面,生命就容易变得比较深刻!

 
 
 

日志

 
 
关于我

别驻足,梦想要不停追逐,别认输,熬过黑暗才有日出,要记住,成功就在下一步,路很苦,汗水是最美的书!

网易考拉推荐
GACHA精选

Minimum Inversion Number  

2010-05-13 17:20:16|  分类: ACM |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

Description

The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that satisfy i < j and ai > aj.

For a given sequence of numbers a1, a2, ..., an, if we move the first m >= 0 numbers to the end of the seqence, we will obtain another sequence. There are totally n such sequences as the following:

a1, a2, ..., an-1, an (where m = 0 - the initial seqence)
a2, a3, ..., an, a1 (where m = 1)
a3, a4, ..., an, a1, a2 (where m = 2)
...
an, a1, a2, ..., an-1 (where m = n-1)

You are asked to write a program to find the minimum inversion number out of the above sequences.

Input

The input consists of a number of test cases. Each case consists of two lines: the first line contains a positive integer n (n <= 5000); the next line contains a permutation of the n integers from 0 to n-1.

Output

For each case, output the minimum inversion number on a single line.

Sample Input

10
1 3 6 9 0 8 5 7 4 2

Sample Output

16
用了O(n^2)超了。发现可以用线段树来做。。。
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
struct Node
{
 int l, r, mid;
 int num;
}tree[20001];
int a[5001];
inline void  make_tree(int left, int right, int now)
{
 tree[now].num = 0;
 tree[now].l = left;
 tree[now].r = right;
 tree[now].mid = (left + right) >> 1;
 if(left == right) return;
 make_tree(left, tree[now].mid, now+now);
 make_tree(tree[now].mid+1, right, now+now+1);
 tree[now].num = max(tree[now+now].num, tree[now+now+1].num);
}
inline void update(int aa, int now)
{
 tree[now].num++;
 if(tree[now].l == tree[now].r)
  return ;
 if(aa <= tree[now].mid) update(aa, now+now);
 else update(aa, now+now+1);
}
inline int query(int left, int right, int now)
{
 if(left == tree[now].l && right == tree[now].r)
  return tree[now].num;
 if(right <= tree[now].mid)   return query(left, right, now+now);
 else if(tree[now].mid < left)    return query(left, right, now+now+1);
 else  return (query(left, tree[now].mid, now+now) + query(tree[now].mid+1, right, now+now+1));
}
int main()
{
 int n, i, cnt;
 while(scanf("%d", &n)!=EOF)
 {
 for(i = 0; i < n; i++)
  scanf("%d", &a[i]);
 make_tree(0, n-1, 1);
 cnt = 0;
 for(i = 0; i < n; i++)
 {
  cnt += query(a[i], n-1, 1);
  update(a[i], 1);
 }
 int ans = cnt;
 for(i = 0; i < n; i++)
 {
  cnt = cnt - a[i] + n - 1 - a[i];
  if(ans > cnt) ans = cnt;
 }
 printf("%d\n", ans);
 }
return 0;
}

  评论这张
 
阅读(687)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017