hdu 1394 Minimum Inversion Number (裸树状数组 求逆序数 && 归并排序求逆序数)
题意:
给一个n个数的序列a1, a2, ..., an ,这些数的范围是0~n-1, 可以把前面m个数移动到后面去,形成新序列:
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)
求这些序列中,逆序数最少的是多少?
树状数组:
分析:c数组里的值代表个数,下标代表等于哪个值,是按照顺序排的,所以sum(n)-sum(a[i]),就能减出来比a[i]大的数值了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <map>
#include <algorithm>
#define LL __int64
const int maxn = +;
using namespace std;
int c[maxn], a[maxn], n; int lowbit(int x)
{
return x&(-x);
}
void add(int x,int d)
{
while(x <= n)
{
c[x] += d;
x +=lowbit(x);
}
}
LL sum(int x)
{
LL ret = ;
while(x > )
{
ret += c[x];
x -= lowbit(x);
}
return ret;
} int main()
{
int i, ans, tmp;
while(~scanf("%d", &n))
{
ans = ;
memset(c, , sizeof(c)); //不要忘了清0
for(i = ; i <= n; i++)
{
scanf("%d", &a[i]);
a[i] ++; //因为是从0到n-1的
ans += sum(n)-sum(a[i]); //貌似a[i]太大的话就不行了吧
add(a[i], ); //c数组里的值代表个数,下标代表等于哪个值
}
tmp = ans;
for(i = ; i <= n; i++)
{
tmp += n-a[i]-(a[i]-); //是一个公式,我没想明白为什么
ans = min(ans, tmp);
}
printf("%d\n", ans);
}
return ;
}
归并排序的做法:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define LL __int64
const int maxn = +;
using namespace std;
int n;
int sum, b[maxn], a[maxn], a2[maxn]; void merge_sort(int *A, int x, int y, int *T)
{
if(y-x>)
{
int m=x+(y-x)/;
int p=x, q=m, i=x;
merge_sort(A,x,m,T);
merge_sort(A,m,y,T);
while(p<m || q<y)
{
if(q>=y ||(p<m && A[p] <= A[q]))
T[i++] = A[p++];
else
{
T[i++] = A[q++];
sum+=m-p;
} }
for(i=x; i<y; i++)
A[i] = T[i];
}
}; int main()
{
int i;
int tmp;
while(~scanf("%d", &n))
{
sum = ;
memset(b, , sizeof(b));
for(i = ; i < n; i++) //注意这是从0开始的,因为归并排序的原因
{
scanf("%d", &a[i]);
a2[i] = a[i];
}
merge_sort(a, , n, b);
tmp = sum;
for(i = ; i < n; i++)
{
tmp += n--a2[i]-a2[i]; //一定要注意这个是a2[]; 因为之前的a[]的顺序已经改变了。还要注意这个公式
sum = min(sum, tmp); //和上一个树状数组的不同是上一个a[]++了。
}
printf("%d\n", sum);
}
return ;
}
hdu 1394 Minimum Inversion Number (裸树状数组 求逆序数 && 归并排序求逆序数)的更多相关文章
- HDU 1394 Minimum Inversion Number (树状数组)
题目链接 Problem Description The inversion number of a given number sequence a1, a2, ..., an is the numb ...
- hdu 1394 Minimum Inversion Number (树状数组求逆序对)
The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that ...
- hdu 1394 Minimum Inversion Number(树状数组)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 题意:给你一个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【 树状数组 】
题意:给出n个数,每次可以把第一个数挪到最后一个位置去,问这n种排列里面的最小逆序对数 先把最开始的逆序对数求出来 然后对于一个数a[i],比它小的数有a[i] - 1个,比它大的数有n - a[i] ...
- HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)
HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...
- HDU 1394 Minimum Inversion Number(线段树 或 树状数组)
题目大意:给出从 0 到 n-1 的整数序列,A0,A1,A2...An-1.可将该序列的前m( 0 <= m < n )个数移到后面去,组成其他的序列,例如当 m=2 时,得到序列 A2 ...
- HDU 1394:Minimum Inversion Number(树状数组,线段树)[水]
题意:有0~n-1这n个数,以一定的排列.这个排列可以循环,就是可以把第一个拿到最后,然后形成新的排列.问这些排列中的逆序对最小值. 思路: 最后的循环,拿走一个之后,新的逆序对数 newsum = ...
- [HDU] 1394 Minimum Inversion Number [线段树求逆序数]
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
随机推荐
- TCP协议三次握手、四次断开 过程分析
建立TCP连接的过程需要进行三次信息交换,通常称为“三次握手”,示意图如下:
- LintCode-Median II
Numbers keep coming, return the median of numbers at every time a new number added. Example For numb ...
- android 开发 实现自动安装
场景:实现自动安装apk程序 注意:不能使用 intent.setDataAndType(Uri.parse(apkPath), "application/vnd.android.pack ...
- 让站长在SEO时更得心应手的六个细节
分析一下SEO的心得,希望能对很多做网站优化和做网站推广的站长有帮助,现在做SEO的人越来网站推广越多,即使很多人在做,但不知道自己能否成功,自己的优化是否会见效,所以在这里还是来分享一下咱们在SEO ...
- 《云大课程助手》Android刷课工具来袭
云大课程助手(Android)谨以此app纪念我这四年的大学生活.希望大家用的愉快. 下载地址:http://zhushou.360.cn/detail/index/soft_id/922292注:已 ...
- 【DP】BZOJ 1260: [CQOI2007]涂色paint
1260: [CQOI2007]涂色paint Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 893 Solved: 540[Submit][Stat ...
- 基于密度的聚类之Dbscan算法
一.算法概述 DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一个比较有代表性的基于密度的聚类算法.与划分和层次 ...
- [CF]codeforces round 369(div2)
*明早起来再贴代码 A [题意] 给定n*5的方格 将横向的相邻两个变成+输出 [题解] ... B [题意] 一个n*n的正整数矩阵,有且仅有一个数为0 ,在这个位置填上一个数,使得每一列的和 每一 ...
- [转载]淘宝API调用 申请 获取session key
http://www.cnblogs.com/zknu/archive/2013/06/14/3135527.html 在调用淘宝的API时,我们都会用到appkey,appsecret,appses ...
- JavaScript高级---适配器模式
一.设计模式 javascript里面给我们提供了很多种设计模式: 工厂.桥.组合.门面.适配器.装饰者.享元.代理.观察者.命令.责任链 在前面我们实现了工厂模式和桥模式 工厂模式 : 核心:为了生 ...