CF1365F
  • 给定 $n$ 和数字串 $a_1,a_2,\cdots,a_n$,$b_1,b_2,\cdots,b_n$。
  • 定义一次操作为:将一个等长且不相交的前缀和后缀对应位置交换。举例:${1,2,3,4,5,6}$ 交换长度为 $2$ 的前后缀变为 ${5,6,3,4,1,2}$。
  • 可以对 $a$ 进行任意次操作,问是否能变成 $b$。多组数据。
  • $1\leq T\leq 500,1\leq n\leq 500,1\leq a_i,b_i\leq 10^9$。

sol

  • 一个显然的结论:如果 $n$ 为奇数,则两个串 $\frac {n+1}2$ 位置必须相同(因为不能翻转)。
  • 我们称下标和为 $n+1$ 的数是对应的(换句话说,第 $i$ 个位置的数和第 $n-i+1$ 位置的数是对应的),那么可以发现,对应位置形成的无序对是永远不会改变的(对于左边的数 $i$ 移动到 $i+(n-k)$,对于右边的数 $n-i+1$ 移动到 $n-i+1-(n-k)$,它们之和依旧为 $n+1$)。
  • 于是大胆猜测原问题等价于是否满足 $a,b$ 无序对相同。

证明

  • 首先,上述结论是必要的。
  • 其次,若对于满足上述结论的 $a$,能构造出合法的操作序列,那么原问题和 $a$ 是否满足上述结论是等价的。接下来需要构造操作序列。
  • 朴素的想法是从中间到两边依次确定,因为固定住中间不影响后续操作,且固定后不影响上述结论是否成立(删除了相同的无序对不影响结论)。
  • 考虑现在固定 $a_i,a_{n-i+1}$,找相同的无序对 $a_j,a_{n-j+1}$ 移动过来。设 $a_i=a_j$,分情况讨论:
    1. $j=n$,那么直接翻转长度为 $i$ 的前后缀,那么 $a_n$ 翻到 $a_i$,$a_1$ 翻到 $a_{n-i+1}$,满足条件;
    2. $j=1$,那么直接翻转长度为 $1$ 的前后缀,就变成 1. 的情况了;
    3. 其它,那么翻转长度为 $j(n-j+1)$ 的前后缀,那么 $j$ 就变成 1./2. 的情况了。
  • 这样就变成规模更小的子问题了,所以证明了满足上述条件即成立。

```cpp

include

using namespace std;
typedef pair pii;
int T,n,a[510],b[510];
pii x[510],y[510];
bool check(){
int m=(n>>1)+1;
if ((n&1)&&a[m]!=b[m]) return false;
for (int i=1;i<m;i++){
x[i]=pii(min(a[i],a[n-i+1]),max(a[i],a[n-i+1]));
y[i]=pii(min(b[i],b[n-i+1]),max(b[i],b[n-i+1]));
}
sort(x+1,x+m); sort(y+1,y+m);
for (int i=1;i<m;i++)
if (x[i]!=y[i]) return false;
return true;
}
int main(){
scanf("%d",&T);
while (T--){
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 (check()) puts("Yes");
else puts("No");
}
return 0;
}
```

本文永久更新地址:

https://blog.hydd.cf/p/cf1365f/

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇