农夫约翰的 头奶牛排成一排,编号 。
它们的排序可以由一个数组 来描述,其中 是位于位置 的奶牛的编号。
约翰希望将它们重新排列为一个不同的顺序。
新顺序用数组 来描述,其中 是位于位置 的奶牛的编号。
假设奶牛开始时的顺序为:
A = 5 1 4 2 3
并假设约翰希望它们重新排列为:
B = 2 5 3 1 4
为了从 顺序重新排列为 顺序,奶牛们进行了许多“循环”移位。
所谓循环移位,是指挑选排列中的若干头奶牛分在一组,组中奶牛进行循环移动位置,即第一头奶牛移动至第二头奶牛的位置,第二头奶牛移动至第三头奶牛的位置,…,最后一头奶牛移动至第一头奶牛的位置。
如上例中,将 号奶牛分在一组进行循环移位,移动过后, 号奶牛移动至位置 号奶牛移动至位置 号奶牛移动至位置 ;将 号奶牛分在另一组进行循环移位,移动过后, 号奶牛位于位置 号奶牛位于位置 ;最终完成重新排列。
每头奶牛都恰好参与一组循环移位,除非其在 中的位置没有变化。
请计算奶牛们完成重新排列,共需多少组循环移位,最长的一组循环移位的长度是多少。
输入格式
第一行包含整数 。
接下来 行包含 。
再接下来 行包含 。
输出格式
输出循环移位的组数,以及最长的一组循环移位的长度。
如果不存在循环移位,则第二个数输出 。
数据范围
输入样例:
5
5
1
4
2
3
2
5
3
1
4
输出样例:
2 3
using namespace std;
const int N = 110;
int n;
int a[N], b[N], bid[N];
int p[N], cnt[N];
int find(int x){
if(x != p[x]) p[x] = find(p[x]);
return p[x];
}
int main(){
for(int i = 1; i < N; i++) p[i] = i;
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= n; i++) cin >> b[i];
for(int i = 1; i <= n; i++){
int px = find(a[i]), py = find(b[i]);
if(px != py) p[px] = py;
}
for(int i = 1; i <= n; i++){
cnt[find(i)]++;
}
int r1 = 0, r2 = 0;
for(int i = 1; i <= n; i++) r2 = max(r2, cnt[i]), r1 += (cnt[i] > 1);
if(r2 == 1) r2 = -1;
cout << r1 << ' ' << r2;
return 0;
}