51nod 1675 序列變換 莫比烏斯反演

題目鏈接點這裏

莫比烏斯反演模板題

看到互質什麼的個數,,就想到莫比烏斯反演了吧,,

我們將f(n)設爲下標gcd剛剛爲n的組數,F(n)爲下標的gcd爲n的倍數的組數。。根據反演公式:



#include<iostream>
#include<cstdio>
#include<math.h>
#include<algorithm>
#include<map>
#include<set>
#include<bitset>
#include<unordered_map>
#include<stack>
#include<queue>
#include<string.h>
#include<cstring>
#include<vector>
#include<time.h>
#include<stdlib.h>
using namespace std;
#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3f
#define FIN freopen("input.txt","r",stdin)
#define mem(x,y) memset(x,y,sizeof(x))
typedef unsigned long long ULL;
typedef long long LL;
#define fuck(x) cout<<"q"<<endl;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef pair<pair<int,int>,int> PIII;
typedef pair<int,int> PII;
const double eps=1e-8;
const int P=1e9+7;
#define MX 1111111//最大範圍
int n,aa[MX],bb[MX],a[MX],b[MX];
int mu[MX],prime[MX];
bool isprime[MX];
void init()
{
    mu[1]=1;
    prime[0]=0;
    mem(isprime,1);
    for(int i=2; i<MX; i++)
    {
        if(isprime[i])prime[++prime[0]]=i,mu[i]=-1;
        for(int j=1; j<=prime[0]&&i*prime[j]<MX; j++)
        {
            isprime[i*prime[j]]=0;
            mu[i*prime[j]]=-mu[i];
            if(i%prime[j]==0)
            {
                mu[i*prime[j]]=0;
                break;
            }
        }
    }
}
int cnt[MX];
inline int read()
{
    int ret=0,c,f=1;
    for(c=getchar(); !(isdigit(c)||c=='-'); c=getchar());
    if(c=='-') f=-1,c=getchar();
    for(; isdigit(c); c=getchar()) ret=ret*10+c-'0';
    if(f<0) ret=-ret;
    return ret;
}
int main()
{
    init();
    FIN;
    while(cin>>n)
    {
        for(int i=1; i<=n; i++)aa[i]=read();
        for(int i=1; i<=n; i++)bb[i]=read();
        for(int i=1; i<=n; i++)
        {
            a[i]=aa[bb[i]];
            b[i]=bb[aa[i]];
        }
        LL ans=0;
        for(int i=1; i<=n; i++)
            if(mu[i])
            {
                LL t=0;
                for(int j=i; j<=n; j+=i)cnt[a[j]]++;
                for(int j=i; j<=n; j+=i)t+=cnt[b[j]];
                for(int j=i; j<=n; j+=i)cnt[a[j]]--;
                ans+=mu[i]*t;
            }
        cout<<ans<<endl;
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章