HDU 1394 Minimum Inversion Number(线段树 或 树状数组)
题目大意:给出从 0 到 n-1 的整数序列,A0,A1,A2...An-1。可将该序列的前m( 0 <= m < n )个数移到后面去,组成其他的序列,例如当 m=2 时,得到序列 A2,A3...An-1,A0,A1 。我们定义逆序对<Ai,Aj>满足 i < j 且Ai > Aj 。 在所有的序列中找出逆序对最少的序列,输出逆序对个数。num[n+1]存储序列元素。
思路: 假设某个序列的逆序对个数为 sum 则下一个序列的逆序对个数为 sum - num[1] + (n - 1) - num[1]。则只需要求出原始序列的逆序对个数计科推出后面的所有序列的逆序对个数。
再输入每个元素的时候统计区间 [num[i]+1,n-1] 之间的元素已经能出现的总次数,则可以用线段树,或树状数组统计。下面给出两种方法的代码。
树状数组:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
#define INF 0x7fffffff
int a[5010],c[5010],n;
int lowbit(int x){
return x & (-x) ;
}
void add(int x,int d){
while(x <= n){
c[x] += d;
x = x + lowbit(x) ;
}
}
int getsum(int x){
int ans = 0;
while(x > 0){
ans += c[x] ;
x = x - lowbit(x) ;
}
return ans ;
}
int main(){
int i,j,x,num[5010];
while(~scanf("%d",&n) && n){
int sum = 0;
memset(c,0,sizeof(c));
for(i=1;i<=n;i++){
scanf("%d",&x) ;
num[i] = x ;
x ++ ;
sum += getsum(n) - getsum(x) ;
add(x,1);
}
int ans = sum ;
for(i=1;i<n;i++){
sum = sum - (num[i] + 1) + n - num[i] ;
ans = min(ans,sum);
}
cout << ans << endl;
}
return 0;
}
线段树
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
#define INF 0x7fffffff
int n,x;
struct node{
int l,r,sum;
}a[20100];
void buildtree(int i,int l,int r){
a[i].l = l ;
a[i].r = r;
a[i].sum = 0;
if(l == r)
return ;
int mid = (l+r)/2;
buildtree((i<<1),l,mid);
buildtree(i*2+1,mid+1,r);
}
int query(int i,int l,int r){
if(l>r)
return 0;
if(a[i].l == l && a[i].r == r)
return a[i].sum;
int sum = 0;
int mid = (a[i].l + a[i].r) / 2 ;
if(r<=mid)
sum = query(i*2,l,r);
else if(l > mid)
sum = query(i*2+1,l,r);
else
sum = query(i*2,l,mid) + query(i*2+1,mid+1,r) ;
return sum ;
}
void update(int i,int x){
if(a[i].l == x && a[i].r == x){
a[i].sum ++;
}
else{
a[i].sum ++;
int mid = (a[i].l + a[i].r) / 2 ;
if(x<=mid)
update(i*2,x);
else
update(i*2+1,x);
}
}
int main(){
int i,j,sum,num[5010];
while(~scanf("%d",&n) && n ){
sum = 0 ;
buildtree(1,0,n-1);
for(i=1;i<=n;i++){
scanf("%d",&x);
num[i] = x ;
sum += query(1,x+1,n-1);
update(1,x);
}
int ans = sum;
for(i=1;i<n;i++)
{
sum = sum - num[i] + n-num[i]-1 ;
ans = min(ans,sum);
}
cout << ans << endl ;
}
return 0;
HDU 1394 Minimum Inversion Number(线段树 或 树状数组)的更多相关文章
- HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)
HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...
- [HDU] 1394 Minimum Inversion Number [线段树求逆序数]
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
- HDU 1394 Minimum Inversion Number (数据结构-段树)
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
- hdu - 1394 Minimum Inversion Number(线段树水题)
http://acm.hdu.edu.cn/showproblem.php?pid=1394 很基础的线段树. 先查询在更新,如果后面的数比前面的数小肯定会查询到前面已经更新过的值,这时候返回的sum ...
- HDU 1394 Minimum Inversion Number 线段树
题目: http://acm.hdu.edu.cn/showproblem.php?pid=1394 没看到多组输入,WA了一万次...... 其实很简单,有人暴力过得,我感觉归并排序.二叉排序树求逆 ...
- HDU 1394 Minimum Inversion Number(线段树求最小逆序数对)
HDU 1394 Minimum Inversion Number(线段树求最小逆序数对) ACM 题目地址:HDU 1394 Minimum Inversion Number 题意: 给一个序列由 ...
- HDU 1394 Minimum Inversion Number ( 树状数组求逆序数 )
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 Minimum Inversion Number ...
- HDU 1394 Minimum Inversion Number(线段树/树状数组求逆序数)
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
- HDU 1394 Minimum Inversion Number(最小逆序数 线段树)
Minimum Inversion Number [题目链接]Minimum Inversion Number [题目类型]最小逆序数 线段树 &题意: 求一个数列经过n次变换得到的数列其中的 ...
随机推荐
- POJ3580---SuperMemo (Splay)
各种操作,区间更新,求最值.翻转.插入.删除.当然是Splay这种神器了. 主要是 revolve这个操作,其实也就是3个区间翻转放到一块, 比如 REVOLVE x y T,T %= (y-x+1) ...
- poj 3186 Treats for the Cows(区间dp)
Description FJ has purchased N (1 <= N <= 2000) yummy treats for the cows who get money for gi ...
- html5 app图片预加载
function Laimgload(){} //图片预加载JS Laimgload.prototype.winHeight = function(){ //计算页面高度 var winHeight ...
- Netty实例-简单的服务端-client实现,凝视具体
书籍推荐: 实例代码 :http://download.csdn.net/detail/jiangtao_st ...
- C# IoC 容器
Unity是Unity是微软patterns& practices组用C#实现的轻量级,可扩展的依赖注入容器,它为方便开发者建立松散耦合的应用程序, 有以下优点: 1.简化了对象的创建,特别是 ...
- Mysql存储引擎概念特点介绍及不同业务场景选用依据
目录 MySQL引擎概述 1 MySAM引擎介绍 2 什么是InnoDB引擎? 3 生产环境中如何批量更改MySQL引擎 4 有关MySQL引擎常见企业面试题 MySQL引擎概述 Mysql表存储结构 ...
- 自定义VS的ItemTemplates 实现任意文件结构
上一篇说到重写IHttpHandler实现前后端分离,这次说一下如何建立一个如下文件结构. VS建立webform时是根据模板来的.C#的模板目录如下: F:\Program Files (x86)\ ...
- VS2010不能打开预编译的网站源码的原因是什么?(转之csdn)
原问题: 今天将写好的一个网站源码目录拷贝到另一台电脑上,但打开时提示: 你要打开一个预编译的网站,你可以查看该站点,但对它进行更改可能会造成该网站停止运行,若要修改站点,建议先编辑原始网站中的 ...
- js改变div宽度
document.getElementById('Content_Right_id').style.width = document.documentElement.clientWidth - 250 ...
- 控制用户的访问之权限、角色【weber出品必属精品】
权限的作用 限制用户对数据的访问 权限的分类 1. 系统权限:能够存取数据库的权限 2. 对象权限:操作数据库对象的内容 系统权限 1.1 如何创建用户: SQL> create user t ...