• 51nod1675-序列变换【莫比乌斯反演】


    正题

    题目连接:http://www.51nod.com/Challenge/Problem.html#problemId=1675


    题目大意

    给出两个长度为(n)的序列(a,b),求有多少对(x,y)满足

    [gcd(x,y)=1且a_{b_x}=b_{a_y} ]

    (1leq nleq 10^5,1leq a_i,b_ileq n)


    解题思路

    额挺明显的一个莫反,枚举约数(d)的时候用一个数组统计一下有多少个(a_{b_x})就好了。

    时间复杂度(O(nlog n))


    code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const ll N=1e5+10;
    ll n,cnt,ans,a[N],b[N],c[N],mu[N],pri[N/10];
    bool v[N];
    void Prime(){
    	mu[1]=1;
    	for(ll i=2;i<=n;i++){
    		if(!v[i])pri[++cnt]=i,mu[i]=-1;
    		for(ll j=1;j<=cnt&&i*pri[j]<=n;j++){
    			v[i*pri[j]]=1;
    			if(i%pri[j]==0)break;
    			mu[i*pri[j]]=-mu[i];
    		}
    	}
    	return;
    }
    signed main()
    {
    	scanf("%lld",&n);
    	for(ll i=1;i<=n;i++)scanf("%lld",&a[i]);
    	for(ll i=1;i<=n;i++)scanf("%lld",&b[i]);
    	Prime();
    	for(ll i=1;i<=n;i++){
    		ll sum=0;
    		for(ll j=i;j<=n;j+=i)c[a[b[j]]]++;
    		for(ll j=i;j<=n;j+=i)sum+=c[b[a[j]]];
    		for(ll j=i;j<=n;j+=i)c[a[b[j]]]--;
    		ans+=sum*mu[i];
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    Iterator 迭代器
    Collection-List
    Collection-Set
    Collection
    多线程
    面向对象<高级>知识点
    链表
    面向对象<基础>知识点
    三层架构和MVC模式详解
    impala为什么比hive快
  • 原文地址:https://www.cnblogs.com/QuantAsk/p/15087156.html
Copyright © 2020-2023  润新知