问题 B: noip2013 火柴排队
时间限制: 1 Sec 内存限制: 128 MB题目描述
涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度。现在将每盒中的火柴各自排成一列,同一列火柴
的高度互不相同,两列火柴之间的距离定义为:∑(ai-bi)^2 ,其中 ai 表示第一列火柴中第 i 个火柴的高度,bi 表示第二
列火柴中第 i 个火柴的高度。每列火柴中相邻两根火柴的位置都可以交换,请你通过交换使得两列火柴之间的距
离最 小。请问得到这个最小的距离,最少需要交换多少次?如果这个数字太大,请输出这个最小交换次数对 99,9
99,997 取模的结果。
的高度互不相同,两列火柴之间的距离定义为:∑(ai-bi)^2 ,其中 ai 表示第一列火柴中第 i 个火柴的高度,bi 表示第二
列火柴中第 i 个火柴的高度。每列火柴中相邻两根火柴的位置都可以交换,请你通过交换使得两列火柴之间的距
离最 小。请问得到这个最小的距离,最少需要交换多少次?如果这个数字太大,请输出这个最小交换次数对 99,9
99,997 取模的结果。
输入
共三行,第一行包含一个整数 n,表示每盒中火柴的数目。
第二行有 n 个整数,每两个整数之间用一个空格隔开,表示第一列火柴的高度。
第三行有 n 个整数,每两个整数之间用一个空格隔开,表示第二列火柴的高度。
1 ≤ n ≤ 100,000,0 ≤火柴高度≤ 2^31 - 1
第二行有 n 个整数,每两个整数之间用一个空格隔开,表示第一列火柴的高度。
第三行有 n 个整数,每两个整数之间用一个空格隔开,表示第二列火柴的高度。
1 ≤ n ≤ 100,000,0 ≤火柴高度≤ 2^31 - 1
输出
输出共一行,包含一个整数,表示最少交换次数对 99,999,997 取模的结果
样例输入
4
2 3 1 4
3 2 1 4
样例输出
1
Hint
最小距离是 0,最少需要交换 1 次,比如:交换第 1 列的前 2 根火柴或者交换第 2 列的前 2 根火柴。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iomanip>
#include<cstdlib>
#include<algorithm>
using namespace std;
struct data
{
int x,y;
}a[1000500],b[1000010];
int c[1000500],d[1000100],r[1000500],h[1000500];
int n;
long long s;
bool cmp(data z1,data z2)
{
return z1.x<z2.x;
}
void mem(int e1,int f1)
{
int m,i,j,k;
if(e1==f1)return;
m=(e1+f1)/2;
mem(e1,m);
mem(m+1,f1);
i=e1;j=m+1;
k=i;
while(i<=m&&j<=f1)//&&k<=m
{
if(h[i]<=h[j])
{
r[k]=h[i];
k++;
i++;
}
else
{
s+=m+1-i;
if(s>99999997)s%=99999997;
r[k]=h[j];
j++;
k++;
}
}
while(i<=m)
{
r[k]=h[i];i++;
k++;
}
while(j<=f1)
{
r[k]=h[j];
j++;
k++;
}
for(int h1=e1;h1<=f1;h1++)
h[h1]=r[h1];
}
int main()
{
// freopen("in.txt","r",stdin);
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i].x);
a[i].y=i;
//e[i]=a[i];
}
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++)
{
c[i]=a[i].y;
//g[a[i].x]=
}
// for(int i=1;i<=n;i++)
// {
// cout<<c[i]<<endl;
//g[a[i].x]=
// }
for(int i=1;i<=n;i++)
{
scanf("%d",&b[i].x);
b[i].y=i;//s[i]=(a[i]-b[i])*(a[i]-b[i]);
//f[i]=b[i];
}
sort(b+1,b+1+n,cmp);
for(int i=1;i<=n;i++)
{
d[b[i].y]=i;
}
for(int i=1;i<=n;i++)
{
h[i]=c[d[i]];
}
// for(int i=1;i<=n;i++)
// {
//cout<<h[i]<<" !!@@"<<endl;
// } //lisan();
// for(int i=1;i<=n;i++)
//{
// }
mem(1,n);
cout<<s;
// while(1);
return 0;
}