序列变换

来源:互联网 发布:最优化第二版课后答案 编辑:程序博客网 时间:2024/06/01 10:43
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示例
31 1 11 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;}


原创粉丝点击