题意:给两个长为 n(1n2000)n(1\le n \le 2000) 个序列 a,ba,b,把这两个序列任意排序,然后令 aa 序列加上一个最小的数 xx 使得 aabb 对应位置的差在模 mm 意义下相等。

一道一开始拿到毫无思路的题(于是求和乱推了一下式子准备 O(n) 求解结果错了)。

容易发现可以 O( n2n ^2 ) 求解,于是我们开始乱暴力。

首先由于 (ai+x)modm=bpi(a _i +x) \bmod m= b _{p _i},可以推出如下式子:

bpiai+mmodm=x b _{p _i} -a _i+m \bmod m=x

首先将 aabb 排序,然后将 bb 复制一遍接在后面,得到一个长为 2n2nbb

然后我们将 aabb 一一对应判断即可,以 bb 中任意一个元素开头共有 nn 个不同的序列 bb,将这 nn 个序列依次和 aa 求出 xx ,判断所有 xx 是否相等即可。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define INF 9223372036854775807LL
using namespace std;
const int maxn=2010;
long long n,m,ans=INF,x=INF;
long long a[maxn],b[maxn<<1];
int main()
{
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%lld",&a[i]);
	sort(a+1,a+n+1);
	for(int i=1;i<=n;i++)
		scanf("%lld",&b[i]);
	sort(b+1,b+n+1);
	for(int i=1;i<=n;i++)
		b[i+n]=b[i];
	for(int i=0;i<n;i++)
	{
		x=(b[1+i]-a[1]+m)%m;
		for(int j=1;j<=n;j++)
			if((b[j+i]-a[j]+m)%m!=x)
			{
				x=INF;
				break;
			}
		ans=min(ans,x);
	}
	printf("%lld",ans);
	return 0;
}