cf1110E Magic Stones 题解

可以进行一种操作, \(c^{'}_i=c_{i+1}+c_{i-1}-c_i\).

给出两个长度为 \(n\) 的序列 \(c,t\),问可不可以通过这种操作让 \(c\) 变成 \(t\) .

\(1\leq n\leq 10^5, 0\leq c_i\leq 2\cdot 10^9, 0\leq t_i\leq 2\cdot 10^9\)

简单的想法,找规律,发现 \(c_i\)\(t_i\) 必须要首尾相同,因为收尾不可被改变,\(c_i-c_{i-1}\)\(t_i-t_{i-1}\) 构成的两个序列可以通过arrange得到。来理性分析一下。

原本的数是 \(c_{i-1},c_{i},c_{i+1}\),差是 \(c_{i}-c_{i-1}, c_{i+1}-c_{i}\).

后来的数变成了 \(c_{i-1},c_{i+1}+c_{i-1}-c_i,c_{i+1}\),差是 \(c_{i+1}-c_i, c_i-c_{i-1}\).

只是把差 swap 了一下。所以如果上面的序列的差可以通过不停 swap 之后得到下面序列的差,那么上面这个序列就可以通过操作得到下面这个序列。

时间复杂度: \(O(n\log n)\)

空间复杂度: \(O(n)\)

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n;
int a[N],b[N];
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	for(int i=1;i<=n;i++)scanf("%d",&b[i]);
	if(n==2){
		for(int i=1;i<=n;i++)if(a[i]!=b[i]){
			printf("No\n");
			return 0; 
		} 
		printf("Yes\n");
		return 0;
	}
	a[n+1]=a[n];b[n+1]=b[n];
	for(int i=n;i>=2;i--)a[i]=a[i]-a[i-1];
	for(int i=n;i>=2;i--)b[i]=b[i]-b[i-1];
	sort(a+2,a+n+1);
	sort(b+2,b+n+1);
	for(int i=1;i<=n+1;i++)if(a[i]!=b[i]){
		printf("No\n");
		return 0;
	}
	printf("Yes\n");
	return 0;
}
posted @ 2026-07-06 12:57  xyangh  阅读(2)  评论(0)    收藏  举报