• HihoCoder


    Sample Input

    6
    1 6 2 5 3 4

    Sample Output

    10

    You are given a {1, 2, ..., n}-permutation a[1], a[2], ..., a[n]. How many pairs of integers (i, j) satisfy 1 ≤ i ≤ j ≤ n and gcd(i, j) = gcd(a[i], a[j]) = 1? Here gcd means greatest common divisor.

    Input

    First line contains an integer n. (1 ≤ n ≤ 200000)

    Second line contains n space-separated integers a[1], a[2], ..., a[n] which form a permutation.

    Output

    One line contains the answer.

    题意:给定N的排列a[],问有多少对(i,j),满足gdc(i,j)=gcd(a[i],a[j])=1;

    思路:我们知道区间互质对统计可以用莫比乌斯来容斥,对于每个数d,其贡献=mu[d]*C(含d的个数,2);

    但是这里有两个条件,可以说是个二维的。 那么,我们枚举第一位的d,然后在第二维里正常的操作。

    复杂度:因为每个数在第一维最多被使用log次,第二维也是,所以复杂度不大于N*logN*logN。加上我们有一些减枝,比如mu[i]=0时不操作。

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=200010;
    int a[maxn],mu[maxn],pos[maxn],num[maxn],N; vector<int>G[maxn]; ll ans;
    void init()
    {
    
        rep(i,1,N) {
            if(i==1) mu[1]=1; G[i].push_back(i);
            for(int j=i+i;j<=N;j+=i) mu[j]-=mu[i],G[j].push_back(i);
        }
    }
    ll get(int x)
    {
        ll res=0;
        for(int i=x;i<=N;i+=x)
          rep(j,0,G[a[i]].size()-1) num[G[a[i]][j]]++;
        for(int i=x;i<=N;i+=x)
          rep(j,0,G[a[i]].size()-1) res+=1LL*(num[G[a[i]][j]]-1)*mu[G[a[i]][j]];
        for(int i=x;i<=N;i+=x)
          rep(j,0,G[a[i]].size()-1) num[G[a[i]][j]]=0;
        return res/2;
    }
    int main()
    {
        scanf("%d",&N); init();
        rep(i,1,N) scanf("%d",&a[i]),pos[a[i]]=i;
        rep(i,1,N)
          if(mu[i]) ans+=1LL*mu[i]*get(i);
        printf("%lld
    ",ans+(a[1]==1));
        return 0;
    }
  • 相关阅读:
    Mybatis详解(二)
    Mybatis详解(一)
    Java集合
    Java基础之IO
    Java异常知识点!
    HTTP状态码
    ajax传字符串时出现乱码问题的解决
    Json 文件 : 出现 Expected value at 1:0 问题的解决
    java @XmlTransient与@Transient区别
    文件的上传和回显
  • 原文地址:https://www.cnblogs.com/hua-dong/p/10222011.html
Copyright © 2020-2023  润新知