zoukankan      html  css  js  c++  java
  • [洛谷P2568]GCD

    题目大意:给你$n(1leqslant nleqslant 10^7)$,求$displaystylesumlimits_{x=1}^ndisplaystylesumlimits_{y=1}^n[(x,y)in m prime]$($(a,b)$为$a,b$的$gcd$)

    题解:可以用莫比乌斯反演来做,同这道题,只需要把$m$改成$n$就行了

    卡点:

    C++ Code:(莫比乌斯反演)

    #include <cstdio>
    #include <cstring>
    #define maxn 10000010
    using namespace std;
    int n;
    int miu[maxn], plist[maxn], ptot;
    int g[maxn];
    bool isp[maxn];
    void sieve(int n) {
    	memset(isp, true, sizeof isp);
    	miu[1] = 1;
    	for (int i = 2; i < n; i++) {
    		if (isp[i]) plist[ptot++] = i, miu[i] = -1;
    		for (int j = 0; j < ptot && i * plist[j] < n; j++) {
    			int tmp = i * plist[j];
    			isp[tmp] = false;
    			if (i % plist[j] == 0) {
    				miu[tmp] = 0;
    				break;
    			}
    			miu[tmp] = -miu[i];
    		}
    	}
    	for (int i = 0; i < ptot; i++) {
    		for (int j  = 1; j * plist[i] < n; j++)
    			g[j * plist[i]] += miu[j];
    	}
    	for (int i = 2; i <= n; i++) g[i] += g[i - 1];
    }
    inline int min(int a, int b) {return a < b ? a : b;}
    long long solve(int n, int m) {
    	long long ans = 0;
    	int i, j;
    	int tmp = min(n, m);
    	for (i = 1; i <= tmp; i = j + 1) {
    		j = min(n / (n / i), m / (m / i));
    		ans += 1ll * (n / i) * (m / i) * (g[j] - g[i - 1]);
    	}
    	return ans;
    }
    int main() {
    	sieve(maxn);
    	scanf("%d", &n);
    	printf("%lld
    ", solve(n, n));
    	return 0;
    }
    

    题解:也可以用也可以用$phi$函数来做。
    $$
    若(x,y)==p(pin m prime)
    Rightarrow ig(dfrac{x}{p},dfrac{y}{p}ig)==1
    $$
    线性筛出每个数的$varphi$,再前缀和一下就行了

    注意,若$x<y$$(x,y)==p$和$(y,x)==p$是两种不同的方案,但只会在算$y$时被加上,所以答案要乘二,但是当$x==y$时答案会多算一遍,所以要减去质数的个数

    卡点:算$varphi$时没开$long;long$

    C++ Code:(phi函数)

    #include <cstdio>
    #include <cstring>
    #define maxn 10000010
    using namespace std;
    int n;
    bool isp[maxn];
    int plist[maxn], ptot;
    long long phi[maxn], ans;
    void sieve(int n) {
    	memset(isp, true, sizeof isp);
    	phi[1] = 1;
    	for (int i = 2; i <= n; i++) {
    		if (isp[i]) {
    			plist[ptot++] = i;
    			phi[i] = i - 1;
    		}
    		for (int j = 0; j < ptot && i * plist[j] <= n; j++) {
    			int tmp = i * plist[j];
    			isp[tmp] = false;
    			if (i % plist[j] == 0) {
    				phi[tmp] = phi[i] * plist[j];
    				break;
    			}
    			phi[tmp] = phi[i] * phi[plist[j]];
    		}
    	}
    }
    int main() {
    	scanf("%d", &n);
    	sieve(n);
    	for (int i = 2; i <= n; i++) phi[i] += phi[i - 1];
    	for (int i = 0; i < ptot; i++) ans += phi[n / plist[i]] << 1;
    	printf("%lld
    ", ans - ptot);
    	return 0;
    }
    
  • 相关阅读:
    git学习笔记
    ExtJs自学教程(1):一切从API開始
    Floodlight 处理交换机增加/移除过程
    飘逸的python
    Mapreduce运行过程分析(基于Hadoop2.4)——(三)
    oracle中LAG()和LEAD()等分析统计函数的使用方法(统计月增长率)
    Linux学习笔记总结
    看完锤子手机公布会直播 有感
    iOS iOS8中 问题&quot;registerForRemoteNotificationTypes: is not supported in iOS 8.0 and later&quot; 解决方式
    读书笔记-HBase in Action-第二部分Advanced concepts-(3)非Javaclient
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9517163.html
Copyright © 2011-2022 走看看