火柴排队
2017-10-12 23:47
134 查看
原题链接:https://www.luogu.org/problem/show?pid=1966#sub
归并排序求逆序对。
本题定义两列火柴的距离等于Sigma( (a[i]-b[i])^2 ),其实如果把这个式子按照完全平方公式展开,可以发现,其中的a[i]^2 和 b[i]^2相加的总和其实是一直保持不变的。
如果想要把距离弄成最小,那就应该在后面的-2a[i]*b[i]上下功夫。
自然可以想到,肯定是让对应的差值最小才能让距离最大。
那么如何保证每位的差值最小呢?
排一遍序即可,第1大对第1大,第2大对第2大……依次类推。可以证明,没有其他做法会比这个做法总差值更小。
那跟逆序对有什么关系啊?
实际上,我们定义一个a数组,让a[match_a[i].rank] = match_b[i].rank,得到这么一个a数组,最后的答案是a数组里的逆序对的个数。
有点人造痕迹明显,但这样做的确是对的。。
求出a数组的逆序对个数便是答案,可以使用正常向二路归并排序。
参考代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define maxn 100005 #define mo 99999997 using namespace std; int n,ans; int a[maxn]; int b[maxn]; struct matches{ int num; int rank; bool operator<(const matches &rhs)const{ return num < rhs.num; } }; matches match_a[maxn]; matches match_b[maxn]; inline int read(){ int num = 0; char c; bool flag = false; while ((c = getchar()) == ' ' || c == '\n' || c == '\r'); if (c == '-') flag = true; else num = c - '0'; while (isdigit(c = getchar())) num = num * 10 + c - '0'; return (flag ? -1 : 1) * num; } void merge_sort(int l,int r){ if (l >= r) return ; int mid = (l+r) >> 1; merge_sort(l,mid); merge_sort(mid+1,r); int i = l; int j = mid + 1; int k = l; while (i <= mid && j <=r){ if (a[i] > a[j]){ b[k++] = a[j++]; ans += mid - i + 1; ans %= mo; } else b[k++] = a[i++]; } while (i <= mid) b[k++] = a[i++]; while (j <= r) b[k++] = a[j++]; for (register int i=l;i<=r;i++) a[i] = b[i]; } int main(){ n = read(); for (register int i=1;i<=n;i++){ match_a[i].num = read(); match_a[i].rank = i; } for (register int i=1;i<=n;i++){ match_b[i].num = read(); match_b[i].rank = i; } sort(match_a+1,match_a+n+1); sort(match_b+1,match_b+n+1); for (register int i=1;i<=n;i++) a[match_a[i].rank] = match_b[i].rank; merge_sort(1,n); printf("%d\n",ans); return 0; }
相关文章推荐
- noip2013火柴排队
- CodeVS3286 NOIP2013 火柴排队
- 归并排序求逆序对 CODEVS 1688 && NOIP 2013 火柴排队
- 火柴排队 Match
- 洛谷p1966 火柴排队 (逆序对变形,目标排序
- NOIP 2013 火柴排队
- [NOIP2013]火柴排队
- NOIP2013 火柴排队
- 【codevs 3286】火柴排队
- 2013NOIP D1 T2 火柴排队
- 【NOIP2013】火柴排队 线段树+逆序对
- Codevs 火柴排队
- 火柴排队 归并 or 树状数组
- [luogu]P1966火柴排队-逆序对与归并排序的初步运用
- [NOIP2013提高&洛谷P1966]火柴排队 题解(树状数组求逆序对)
- NOIP2013提高组复赛 火柴排队 解题报告
- noip2013 火柴排队 (离散化+归并排序求逆序对数)
- 3286 火柴排队
- COdevs 3286 火柴排队
- wikioi3286 noip2013 火柴排队 归并求逆序对