题意:
有两个数组,分别为操作数组
c
c
c与目标数组
t
t
t
一次操作选择
1
<
i
<
n
1<i<n
1<i<n,使
c
i
c_i
ci变为
c
i
′
=
c
i
+
1
+
c
i
−
1
−
c
i
c_i'=c_{i+1}+c_{i-1}-c_i
ci′=ci+1+ci−1−ci
是否能做若干次操作,使每个
c
i
c_i
ci和
t
i
t_i
ti相等
分析:
我们设
s
i
s_i
si为差分数组,有
s
i
=
c
i
−
c
i
−
1
s_i=c_{i}-c_{i-1}
si=ci−ci−1
考虑当我们改变
c
i
c_i
ci时,
s
i
&
s
i
+
1
s_i\& s_{i+1}
si&si+1的变化
s
i
=
c
i
−
1
+
c
i
+
1
−
c
i
−
c
i
−
1
=
c
i
+
1
−
c
i
s_i=c_{i-1}+c_{i+1}-c_i-c_{i-1}=c_{i+1}-c_i
si=ci−1+ci+1−ci−ci−1=ci+1−ci
s
i
+
1
=
c
i
+
1
−
c
i
+
1
−
c
i
−
1
+
c
i
=
c
i
−
c
i
−
1
s_{i+1}=c_{i+1}-c_{i+1}-c_{i-1}+c_i=c_i-c_{i-1}
si+1=ci+1−ci+1−ci−1+ci=ci−ci−1
也就是相当于每次操作本质上就是交换了差分数组中相邻的位置,那么可行性就很好判定了
代码:
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<cmath>
#define LL long long
using namespace std;
inline LL read() {
LL d=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
return d*f;
}
int a[100005],b[100005],c1[100005],c2[100005];
int main()
{
int n=read();
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<=n;i++) b[i]=read();
if(a[1]!=b[1]||a[n]!=b[n]) return !printf("No");
for(int i=1;i<n;i++) c1[i]=a[i+1]-a[i],c2[i]=b[i+1]-b[i];
sort(c1+1,c1+n);sort(c2+1,c2+n);
for(int i=1;i<n;i++) if(c1[i]!=c2[i]) return !printf("No");
printf("Yes");
return 0;
}