【洛谷CF1110E】Magic Stones
题目描述
多个询问,
每个询问给出长度为n的2个序列a,b
每次可以对1<i<n的ai进行操作,
操作后:
问能否通过若干次操作,使得序列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
ai′−ai+1=ai−1−ai
a
i
′
−
a
i
−
1
=
a
i
+
1
−
a
i
a_i'-a{i-1}=a_{i+1}-a_i
ai′−ai−1=ai+1−ai
我们可以发现,这个操作就是把当前数的相邻的两个差分交换位置。
那么我们就求出这两个数列的差分,然后一一匹配就可以了,注意,输入样例比较大,所以要用快读,否则会超时
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;
}