【NOIP2013提高组】火柴排队
2016-08-01 17:08
567 查看
题目大意:给你两个有序数组a,b并定义a,b间的距离为∑(ai-bi)^2,要求交换a或者b中的某些元素的位置使得a,b间距离最小。
由于∑(ai-bi)^2=∑(ai^2)+∑(bi^2)-2*∑aibi;而由于题目给定了ai,bi的值,所以∑(ai^2)、∑(bi^2)是定值,要求原式最小就需要∑aibi最大。
而根据排序不等式原理,∑aibi最大值是ai,bi的顺序和。
所以先把ai按照高度排好序,bi也按照高度排好序。题目所求就是排好序的ai和bi编号要求1~6一一对应时的排序次数。
用一个数组记录ai,bi编号间的对应关系,再求逆序对个数即可。
#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<cstdlib> #include<cstring> #define mo 99999997 #define maxn 100010 using namespace std; typedef long long LL; int n; struct data { int v,id; }A[maxn],B[maxn]; bool cmp(data a,data b) { return a.v<b.v; } int x[maxn],t[maxn]; LL merge_sort(int x,int y,int *a) { if(x>=y)return 0; int m=x+y>>1; LL t1=merge_sort(x,m,a); LL t2=merge_sort(m+1,y,a); LL t3=0; int i=x,j=m+1,k=x; while(i<=m && j<=y) { if(a[i]>a[j]) { t[k++]=a[j++]; t3=(t3%mo+(m-i+1)%mo)%mo; } else { t[k++]=a[i++]; } } while(i<=m)t[k++]=a[i++]; while(j<=y)t[k++]=a[j++]; for(int i=x;i<=y;i++) a[i]=t[i]; return (t1+t2+t3)%mo; } int main() { //freopen("match.in","r",stdin); //freopen("match.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&A[i].v); A[i].id=i; } for(int i=1;i<=n;i++) { scanf("%d",&B[i].v); B[i].id=i; } sort(A+1,A+n+1,cmp); sort(B+1,B+n+1,cmp); for(int i=1;i<=n;i++) x[A[i].id]=B[i].id; LL ans=merge_sort(1,n,x); cout<<ans<<endl; return 0; }
相关文章推荐
- NOIP 2013 提高组 Day1 T2 火柴排队【逆序对】
- 【NOIP2013提高组】火柴排队
- Noip提高2013 Day1 T2 火柴排队 归并求逆序对
- 洛谷P1966 [NOIP2013提高组Day1T2]火柴排队
- 「2013NOIP提高组」火柴排队
- NOIP2013复赛提高组day1(A:转圈游戏 B:火柴排队 C:货车运输)
- NOIP2013提高组 火柴排队 (分治逆序对)
- 【NOIP2013提高组day1】火柴排队
- NOIP2013提高组 B.火柴排队 (逆序对)
- NOIp 2013 提高组 火柴排队 题解
- 【noip2013提高组】火柴排队 树状数组+逆序对
- NOIP 提高组2013 火柴排队 (Vijos P1842)
- [NOIP2013提高&洛谷P1966]火柴排队 题解(树状数组求逆序对)
- NOIP2013提高组 火柴排队(重庆一中高2018级信息学竞赛测验6) 解题报告
- NOIP提高组2013 火柴排队
- NOIP2013提高组 火柴排队 (逆序对+特殊映射)
- 洛谷P1966 火柴排队[NOIP提高组2013]
- NOIP 2013 - 提高组 火柴排队 归并排序+逆序对 重庆一中高2018级竞赛班第六次测试 2016.7.31 Problem 4
- 【NOIP】提高组2013 火柴排队
- 【NOIP 2013 DAY.1】火柴排队【codevs 3286】