列表

详情


NC16526. [NOIP2013]火柴排队

描述

有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度。 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为:
其中 ai 表示第一列火柴中第 i 个火柴的高度, bi 表示第二列火柴中第 i 个火柴的高度。
每列火柴中相邻两根火柴的位置都可以交换,请你通过交换使得两列火柴之间的距离最小。请问得到这个最小的距离,最少需要交换多少次?如果这个数字太大,请输出这个最小交换次数对 99,999,997 取模的结果。

输入描述

共三行,第一行包含一个整数 n ,表示每盒中火柴的数目。
第二行有 n 个整数,每两个整数之间用一个空格隔开,表示第一列火柴的高度。
第三行有 n 个整数,每两个整数之间用一个空格隔开,表示第二列火柴的高度。

输出描述

一个整数,表示最少交换次数对 99,999,997 取模的结果。

示例1

输入:

4
2 3 1 4
3 2 1 4

输出:

1

说明:

最小距离是 0 ,最少需要交换 1 次,比如:交换第 1 列的前 2 根火柴或者交换第 2 列的前 2 根火柴。

示例2

输入:

4
1 3 4 2
1 7 2 4

输出:

2

说明:

最小距离是 10 ,最少需要交换 2 次,比如:交换第 1 列的中间 2 根火柴的位置,再交换第 2 列中后 2 根火柴的位置。

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 110ms, 内存消耗: 7160K, 提交时间: 2019-11-23 14:24:50

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e6+10;
const int mode=99999997;
typedef long long ll;
struct no
{
	ll num;
	int id;
}a[maxn],b[maxn],q[maxn];
bool cmp(no aa,no bb)
{
	 return aa.num<bb.num;
}
int n;
ll sum[maxn];
int lowbit(int x)
{
	 return x&(-x);
}
void add(int x)
{
	while(x<=n)
	{
		 sum[x]++;
		 x+=lowbit(x);
	}
}
int get(int x)
{
	 int ans=0;
	 while(x)
	 {
	 	 ans+=sum[x];
	 	 x-=lowbit(x);
	 }
	 //cout<<ans<<endl;
	 return ans;
}
int main()
{

cin>>n;
for(int i=1;i<=n;i++)
{
	 cin>>a[i].num;
	 a[i].id=i;
}
for(int i=1;i<=n;i++)
{
	 cin>>b[i].num;
	 b[i].id=i;
}
sort(a+1,a+1+n,cmp);
sort(b+1,b+1+n,cmp);
for(int i=1;i<=n;i++)  q[a[i].id].num=b[i].id;
ll ans=0;
for(int i=n;i;i--)
{
	   ans+=get(q[i].num)%mode;
	   ans=ans%mode;
	   add(q[i].num);
}
cout<<ans<<endl;
return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 37ms, 内存消耗: 2788K, 提交时间: 2019-09-19 15:44:09

#include<bits/stdc++.h>
using namespace std;
const int NN=1e5+4,P=99999997;
int n,a[NN],b[NN],c[NN];
int lower(int x)
{
	return x&(-x);
}
void add(int x)
{
	while(x)
	{
		c[x]++;
		x-=lower(x);
	}
}
int get(int x)
{
	int sum=0;
	while(x<=n)
	{
		sum+=c[x];
		x+=lower(x);
	}
	return sum;
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		int x;
		scanf("%d",&x);
		a[x]=i;
	}
	for(int i=1;i<=n;i++)
	{
		int x;
		scanf("%d",&x);
		b[i]=a[x];
	}
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		ans=(ans+get(b[i]+1))%P;
		add(b[i]);
	}
	printf("%d",ans);
	return 0;
}

上一题