题意:
见题面。
思路:
设
f
(
n
)
为
g
c
d
(
x
,
y
)
为
n
的
序
对
的
对
数
,
g
(
n
)
为
g
c
d
(
x
,
y
)
为
n
的
倍
设f(n)为gcd(x,y)为n的序对的对数,g(n)为gcd(x,y)为n的倍
设f(n)为gcd(x,y)为n的序对的对数,g(n)为gcd(x,y)为n的倍
数
的
序
对
的
个
数
,
数的序对的个数,
数的序对的个数,
那么显而易见的:g(n) =
∑
n
∣
i
f
(
i
)
\sum_{n|i}f(i)
∑n∣if(i),
这个式子反演后得:
f
(
n
)
=
∑
n
∣
i
m
u
(
i
)
∗
g
(
i
/
n
)
f(n) = \sum_{n|i}mu(i)*g(i/n)
f(n)=∑n∣imu(i)∗g(i/n),
而我们要求的n=1,则:
f
(
1
)
=
∑
n
∣
i
m
u
i
∗
g
(
i
)
f(1) = \sum_{n|i}mu{i}*g(i)
f(1)=∑n∣imui∗g(i)
即我们要从1到n枚举i,算得它得g(i),再加和即可。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
ll a[100010],b[100010],num[100010];
ll cnt,pri[100010],mu[100010],vis[100010];
ll res[100010];
void oula()
{
for(int i = 2; i <= 100000; i++)
{
if(!vis[i])pri[++cnt] = i,mu[i] = -1;
for(int j = 1; j <= cnt && pri[j]*i <= 100000; j++)
{
vis[pri[j]*i] = 1;
if(i%pri[j] == 0)break;
mu[pri[j]*i] = -mu[i];
}
}
}
int main()
{
mu[1] = 1;
oula();
int n;
cin>>n;
ll ans = 0;
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 f = mu[i];
for(int j = i; j <= n; j+=i)num[a[b[j]]]++;
for(int j = i; j <= n; j+=i)ans += num[b[a[j]]]*f;
for(int j = i; j <= n; j+=i)num[a[b[j]]] = 0;
}
cout<<ans<<endl;
}