【洛谷CF1110E】Magic Stones


题目描述

多个询问,

每个询问给出长度为n的2个序列a,b

每次可以对1<i<n的ai进行操作,

操作后:

【洛谷CF1110E】Magic Stones_#include

问能否通过若干次操作,使得序列a变成 b

输入格式

给出询问数T

第一行一个正整数n

第二行给出序列a

第三行给出序列b

输出格式

是否能转变,输出Yes或者No,每个询问对应一行

输入样例

样例1

1
4
7 2 4 12
7 15 10 12


样例2

1
3
4 4 4
1 2 3


输出样例

样例1

Yes


样例2

No


解题思路

首先我们观察公式,通过移项可以得到以下两个式子:

$a_i'-a_{i+1}=a_{i-1}-a_i$

$a_i'-a{i-1}=a_{i+1}-a_i$

我们可以发现,这个操作就是把当前数的相邻的两个差分交换位置。

那么我们就求出这两个数列的差分,然后一一匹配就可以了,注意,输入样例比较大,所以要用快读,否则会超时

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define getchar() ((S==T&&(T=(S=buffer)+fread(buffer,1,1<<15,stdin),S==T))?EOF:*S++)
char buffer[1<<15],*S=buffer,*T=buffer;
using namespace std;
inline int read()//快读
{
int m=0,n=1;
char ch;
ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
n=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
m=m*10+ch-'0';
ch=getchar();
}
return m*n;
}
int a[100010],sum1[100010],sum2[100010];
inline bool pd(int a[],int b[],int n)//判断是否全等
{
bool ok=1;
for(int i=1;i<=n;i++)
if(a[i]!=b[i])
{
ok=0;
break;
}
if(ok==0) return false;
return true;
}
int main()
{
int t,n,k;
t=read();
for(int i=1;i<=t;i++)
{
n=read();
a[1]=read();
for(int j=2;j<=n;j++)
{
a[j]=read();
sum1[j-1]=abs(a[j]-a[j-1]);//求出数列的差分
}
a[1]=read();
for(int j=2;j<=n;j++)
{
a[j]=read();
sum2[j-1]=abs(a[j]-a[j-1]);
}
sort(sum1+1,sum1+n);
sort(sum2+1,sum2+n);
if(pd(sum1,sum2,n-1)==true)
cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}


谢谢阅读