zoukankan      html  css  js  c++  java
  • P3455 [POI2007]ZAP-Queris(莫比乌斯反演)

    题意:

    给出(a,b,d),求满足(1 leq x leq a,1 leq y leq b),且(gcd(x,y)=d)的二元组((x,y))的数量。

    (1 leq n leq 5 imes 10^4)

    (1 leq d leq a,b leq 5 imes 10^4)

    题解:

    写出式子:

    (sum_{i=1}^asum_{j=1}^b[gcd(i,j)=k])

    可以把(d)提取出来,变成

    (sum_{i=1}^{a/k}sum_{i=1}^{b/k}[gcd(i,j)=1])

    可以把(gcd(i,j)=1)变成(sum_{d|gcd(i,j)}mu(d))(莫比乌斯函数的性质),变成

    (sum_{i=1}^{a/k}sum_{j=1}^{b/k}sum_{d|gcd(i,j)}mu(d))

    (i,j)都是(d)的倍数,且(d)的范围一定是(min(a,b))

    这里默认(a)是较小的那个,

    所以可以把(d)移到前面,变成

    (sum_{d=1}^amu(d)[n/kd][m/kd])

    然后套一个二维的数论分块,时间复杂度(O(sqrt{n}))

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+100;
    typedef long long ll;
    int vis[maxn];
    ll pri[maxn],mu[maxn],sum[maxn],cnt;
    void getMu (ll n) {
    	//线性筛莫比乌斯函数,并求解前缀和 
    	mu[1]=1;
    	for (ll i=2;i<=n;i++) {
    		if (!vis[i]) {
    			mu[i]=-1;
    			pri[++cnt]=i;
    		}
    		for (ll j=1;j<=cnt&&i*pri[j]<=n;j++) {
    			vis[i*pri[j]]=1;
    			if (i%pri[j]==0) break;
    			else mu[i*pri[j]]=-mu[i];
    		}
    	}
    	for (ll i=1;i<=n;i++) sum[i]=sum[i-1]+mu[i];
    }
    int main () {
    	int _;
    	scanf("%d",&_);
    	getMu(60000);
    	while (_--) {
    		ll A,B,D;
    		scanf("%lld%lld%lld",&A,&B,&D);
    		if (A>B) swap(A,B);
    		ll ans=0;
    		for (ll l=1,r;l<=A;l=r+1) {
    			r=min(A/(A/l),B/(B/l));
    			ans+=(A/(l*D))*(B/(l*D))*(sum[r]-sum[l-1]);
    		}
    		printf("%lld
    ",ans);
    	}
    }
    
  • 相关阅读:
    python基础学习(九)
    python基础学习(八)
    python基础学习(七)
    python基础学习(六)
    python基础学习(五)
    python基础学习(四)
    python基础学习(三)
    mysql-binlog server的实现
    percona-toolkit常用工具
    Linux下如何快速定位系统瓶颈在哪里
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/15001658.html
Copyright © 2011-2022 走看看