H y p e r l i n k Hyperlink Hyperlink
http://codeforces.com/problemset/problem/1110/E
D e s c r i p t i o n Description Description
给定两个长度为
n
n
n度序列
A
,
B
A,B
A,B
对于
A
A
A中的一个数
A
i
A_i
Ai,你可以将其变成
A
i
‘
=
A
i
+
1
+
A
i
−
1
−
A
i
,
i
∈
(
1
,
n
)
A_i^`=A_{i+1}+A_{i-1}-A_i,i\in(1,n)
Ai‘=Ai+1+Ai−1−Ai,i∈(1,n)
问是否存在一种方案,使得
A
A
A变成
B
B
B
数据范围: n ≤ 1 0 5 n\leq 10^5 n≤105
S o l u t i o n Solution Solution
首先由于 i i i范围的受限,第一位和第 n n n位的 A , B A,B A,B必须对应相等
考虑转换操作,以下均满足
i
∈
(
1
,
n
)
i\in(1,n)
i∈(1,n)
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
−
A
i
−
1
a_i=A_i-A_{i-1}
ai=Ai−Ai−1(即
A
A
A的差分数组),现在
A
i
A_i
Ai变成了
A
i
+
1
+
A
i
−
1
−
A
i
A_{i+1}+A_{i-1}-A_i
Ai+1+Ai−1−Ai
带入
a
i
a_i
ai得到
a
i
=
A
i
+
1
+
A
i
−
1
−
A
i
−
A
i
−
1
=
A
i
+
1
−
A
i
=
a
i
+
1
a_i=A_{i+1}+A_{i-1}-A_i-A_{i-1}=A_{i+1}-A_i=a_{i+1}
ai=Ai+1+Ai−1−Ai−Ai−1=Ai+1−Ai=ai+1
也就是说,对 A i A_i Ai执行一次上述操作,相当于做一次 s w a p ( a i , a i + 1 ) swap(a_i,a_{i+1}) swap(ai,ai+1)
而我们知道,差分数组相同的两个数组自然也相同
问题转换成为给定两个差分数组 a , b a,b a,b,每次可以交换 a a a的两个相邻的数(其实相当于可以随意调顺序了,因为可以操作无限次),是否存在一种方案,使得 a = b a=b a=b
显然对 a , b a,b a,b排序后判断是否相同即可
时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
C o d e Code Code
#include<cctype>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;int n,a[100010],b[100010];
inline LL read()
{
char c;LL d=1,f=0;
while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48;
while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
return d*f;
}
signed main()
{
n=read();
for(register int i=1;i<=n;i++) a[i]=read();
for(register int i=1;i<=n;i++) b[i]=read();
if(a[1]!=b[1]||a[n]!=b[n]) return puts("No")&0;
for(register int i=1;i<=n;i++) a[i]=a[i+1]-a[i],b[i]=b[i+1]-b[i];
sort(a+1,a+1+n);sort(b+1,b+1+n);
for(register int i=1;i<=n;i++) if(a[i]!=b[i]) return puts("No")&0;
puts("Yes");
}