lyk有两序列a和b。
lyk想知道存在多少对x,y,满足以下两个条件。
1:gcd(x,y)=1。
2:
abx
=
bay
。
例如若a={1,1,1},b={1,1,1}。那么存在7对,因为除了x=2,y=2或x=3,y=3外都满足条件。
Input
第一行一个数n(1<=n<=100000)。 接下来一行n个数,表示ai(1<=ai<=n)。 接下来一行n个数,表示bi(1<=bi<=n)。
Output
一行表示答案
Input示例
3 1 1 1 1 1 1
Output示例
7 思路:利用莫比乌斯反演
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const int SIZE = 1e5 + 10;
bool check[SIZE];
int prime[SIZE];
int mu[SIZE];
int n;
int a[SIZE];
int b[SIZE];
int vis[SIZE];
void init()
{
memset(check, false, sizeof(check));
mu[1] = 1;
int index = 0;
for (int i = 2; i <= SIZE; i++)
{
if (!check[i])
{
prime[index++] = i;
mu[i] = -1;
}
for (int j = 0; j < index && (i*prime[j] <= SIZE); j++)
{
check[i * prime[j]] = true;
if (i % prime[j] == 0)
{
mu[i * prime[j]] = 0;
break;
}
else
{
mu[i * prime[j]] = -mu[i];
}
}
}
}
ll fun(int t)
{
ll result = 0;
for (int i = t; i <= n; i += t)
{
vis[b[a[i]]]++;
}
for (int i = t; i <= n; i += t)
{
result += vis[a[b[i]]];
}
for (int i = t; i <= n; i += t)
{
vis[b[a[i]]]--;
}
return result;
}
int main()
{
init();
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
for (int i = 1; i <= n; i++)
{
cin >> b[i];
}
ll result = 0;
for (int i = 1; i <= n; i++)
{
result += mu[i] * fun(i);
}
cout << result << endl;
return 0;
}