传送门:51nod 1675
题意:中文题。
思路:明明很像多校的一个题,还是简化版,而我愣是没想起来用莫比乌斯反演。。
这题用的是莫比乌斯反演的第二种转化形式:
设f[i]为最大公因数为i时的计数
F[i]为公因数包含i的时候的计数
显然满足第一个式子,因此我们就可以转化成二个式子求出f[1].
代码:
#include<stdio.h>
#include<bits/stdc++.h>
#define MAXN 100010
using namespace std;
int a[MAXN], b[MAXN], cnt[MAXN], mu[MAXN];
long long F[MAXN];
void mobius(int n)
{
mu[1]=1;
for(int i=1;i<=n;i++)
for(int j=i+i;j<=n;j+=i)
mu[j]-=mu[i];
}
int main()
{
int n;
long long ans = 0;
scanf("%d", &n);
mobius(n);
for(int i = 1; i <= n; i++)
scanf("%d", a + i);
for(int i = 1; i <= n; i++)
scanf("%d", b + i);
for(int i = 1; i <= n; i++)
{
for(int j = i; j <= n; j += i) cnt[a[b[j]]]++;
for(int j = i; j <= n; j += i) F[i] += cnt[b[a[j]]];//将a[b[x]] == b[a[y]]的pair数量加到F[i]里(gcd(x, y) == i)
for(int j = i; j <= n; j += i) cnt[a[b[j]]] = 0;
}
for(int i = 1; i <= n; i++) ans += mu[i] * F[i];//莫比乌斯反演求得f[1]
cout << ans << endl;
return 0;
}