alice132

 

2025.12.27 作业 - P12673 「LAOI-8」Change

题目描述

给定一个序列 \(A\) 和一个目标序列 \(B\),序列中的每个元素互不相同,每次操作可以选定一组 \(i,j\),满足 \(j-i=k\)\(k\)正整数,交换 \(a_i,a_j\)

保证 \(A\not=B\),保证经过排序后的 \(A,B\) 相等。

请你求出所有的 \(k\) 使得 \(A\) 可以经过若干次操作变为 \(B\)

输入格式

第一行一个正整数 \(n\)
第二行 \(n\) 个整数表示 \(A\)
第三行 \(n\) 个整数表示 \(B\)

输出格式

若有 \(m\) 个满足要求的整数 \(k\),请输出 \(m\) 行,每行一个正整数。

请按照升序输出所有满足要求的 \(k\)

输入输出样例 #1

输入 #1

5
1 2 3 4 5
1 2 3 5 4

输出 #1

1

输入输出样例 #2

输入 #2

5
1 2 3 5 4
1 3 4 2 5

输出 #2

1

输入输出样例 #3

输入 #3

5
1 4 3 2 5
1 2 3 4 5

输出 #3

1
2

说明/提示

本题采用捆绑测试。

子任务编号 \(n\) 特殊性质 分值
\(1\) \(\le7\) \(10\)
\(2\) \(\le2000\) \(20\)
\(3\) \(\le2\times10^5\) \(\texttt a\) \(30\)
\(4\) \(\le2\times10^5\) \(40\)

特殊性质 \(\texttt a\)\(A\)\(B\) 仅两个元素位置不同。

对于 \(100\%\) 的数据,满足 \(3\le n\le 2 \times10^5\)\(1\le A_i,B_i \le 10^9\)

题解

  1. 将数组\(\{b_i\}\) 替换为 序列 \(\{1,2,..,n\}\) ,表达方式为:\(w[b[i]]=i\) ,数值 \(b[i]\) 转换为 \(i\) 。用此规则转化数组 \(\{a[i]\}\)
  2. 数组A通过交换的方式转换为数组B,转换为:数组A的的排序问题。
    \(i\) 个数 \(a[i]\) 的目标位置为 \(a[i]\),移动距离为 \(|a[i]-i|\).
  3. \(Ans=gcd(|a_i-i|), 1 \le i \le n\) , \(Ans\) 为最大的交换距离。
  4. \(Ans\) 的所有因子均为可行的交换距离。
#include <iostream>
#include <map>
using namespace std;
int n,a[1000005],b[1000005];
map<int,int> w;
int gcd(int a, int b) {
    while (b != 0) {
        int temp = b;b = a % b; a = temp;
    }
    return a;
}

int main() {
    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]),w[b[i]]=i;
    for (int i=1;i<=n;i++) a[i]=w[a[i]];
    int m=0;
    for (int i=1;i<=n;i++)
        b[i]=abs(a[i]-i),m=max(m,b[i]);
    for (int i=1;i<=n;i++) m=gcd(m,b[i]);
    for (int i=1;i<=m;i++)
        if (m%i==0) cout<<i<<endl;
    return 0;
}

posted on 2026-01-21 20:21  alice_ss  阅读(1)  评论(0)    收藏  举报

导航