zoukankan      html  css  js  c++  java
  • P2257 YY的GCD(莫比乌斯反演)

    题意:

    (sum_{i=1}^nsum_{j=1}^m[gcd(i,j)=prime])

    题解:

    首先把(prime)换成(k),和前几题的做法一样,可以快速推导到这一步:

    (sum_{k=1}^nsum_{d=1}^{n/k}mu(d)[n/kd][m/kd][k=prime])

    然后暴力枚举每个质数作为(k)的情况,会T。

    可以进一步优化:

    (T=kd),有

    (sum_{k=1}^nsum_{d=1}^{n/k}mu(d)[n/T][m/T][k=prime])

    把前面两个(sum)改成枚举(T,k)的形式?(我好像悟了...)

    那么可以写成

    (sum_{T=1}^n[n/T][m/T]sum_{k|T}mu(T/k)[k=prime])

    发现后面,这个(sum_{k|T}mu(T/k)[k=prime])是可以预处理出来的。

    即考虑每个质数(k),对(k)的倍数(T),将(T)的答案加上(mu(T/k))

    所以做法就是:

    先线性筛出(n)以内的质数和莫比乌斯函数

    然后预处理出这个柿子后半部分的答案。

    然后预处理出每个(T)的后半部分的答案的前缀和。

    然后直接数论分块做一下即可。

    时间复杂度(O(n+Tsqrt{n}))

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e7+100;
    typedef long long ll;
    int vis[maxn];
    ll pri[maxn],mu[maxn],sum[maxn],cnt;
    ll mm[maxn];
    void getMu (int n) {
    	mu[1]=1;
    	for (int i=2;i<=n;i++) {
    		if (!vis[i]) {
    			mu[i]=-1;
    			pri[++cnt]=i;
    		}
    		for (int 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 (int i=1;i<=cnt;i++) {
    		for (int j=pri[i];j<=n;j+=pri[i])
    			mm[j]+=mu[j/pri[i]];	
    	}
    	for (int i=1;i<=n;i++) sum[i]=sum[i-1]+mm[i];
    }
    main () {
    	getMu(1e7);
    	int _;
    	scanf("%d",&_);
    	while (_--) {
    		int n,m;
    		scanf("%d%d",&n,&m);
    		ll ans=0;
    		if (n>m) swap(n,m);
    		for (int l=1,r;l<=n;l=r+1) {
    			r=min(n/(n/l),m/(m/l));
    			ans+=1ll*(n/l)*(m/l)*(sum[r]-sum[l-1]);
    		}
    		printf("%lld
    ",ans);
    	}
    }
    
  • 相关阅读:
    LeetCode Array Easy 414. Third Maximum Number
    LeetCode Linked List Medium 2. Add Two Numbers
    LeetCode Array Easy 283. Move Zeroes
    LeetCode Array Easy 268. Missing Number
    LeetCode Array Easy 219. Contains Duplicate II
    LeetCode Array Easy 217. Contains Duplicate
    LeetCode Array Easy 189. Rotate Array
    LeetCode Array Easy169. Majority Element
    LeetCode Array Medium 11. Container With Most Water
    LeetCode Array Easy 167. Two Sum II
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/15003727.html
Copyright © 2011-2022 走看看