zoukankan      html  css  js  c++  java
  • LGOJ2568 GCD

    Description

    link

    给定整数(n)(1 leq x,y leq n)(gcd(x,y))为质数的((x,y))的对数

    [1leq nleq 10^7 ]

    Solution

    (O(n^2space log space n))的枚举肯定会爆,所以我们换一个统计方法

    从质数入手,所以题意转化为求

    [sum _ {p in prime} sum _ {i=1} ^{n} sum_{j=1}^n [gcd(i,j)==p] ]

    处理(gcd) ,进行套路性变形

    [sum _ {p in prime} sum _ {i=1} ^{lfloor frac{n}{p} floor} sum _ {j=1} ^{lfloor frac{n}{p} floor} [gcd(i,j)==1] ]

    下面我们改变(j)的枚举上界(就是因为有对称性嘛)

    [sum _ {p in prime} sum _ {i=1} ^{lfloor frac{n}{p} floor}(2 imes sum _ {j=1} ^{i} [gcd(i,j)==1]-1) ]

    这里的减(1)是因为(i=j=1)的时候答案会被重复统计

    这个地方显然是有一些我们很熟悉的东西:(varphi)

    线性筛欧拉函数和质数就完事了

    CODE

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    namespace yspm{
    	inline int read()
    	{
    		int res=0,f=1; char k;
    		while(!isdigit(k=getchar())) if(k=='-') f=-1;
    		while(isdigit(k)) res=res*10+k-'0',k=getchar();
    		return res*f;
    	}
    	const int N=1e7+10,M=1e6+10;
    	int n,tot,p[M],phi[N],sum[N];
    	bool fl[N];
    	inline void prework()
    	{
    		phi[1]=1;
    		for(int i=2;i<=n;++i)
    		{
    			if(!fl[i]) p[++tot]=i,phi[i]=i-1;
    			for(int j=1;j<=tot&&i*p[j]<=n;++j)
    			{
    				fl[i*p[j]]=1; 
    				if(i%p[j]==0){phi[i*p[j]]=phi[i]*p[j]; break;}
    				else phi[i*p[j]]=phi[i]*phi[p[j]];
    			}
    		} for(int i=1;i<=n;++i) sum[i]=sum[i-1]+phi[i];
    		return ;
    	}
    	signed main()
    	{
    		n=read(); prework(); int ans=0;
    		for(int i=1;i<=tot;++i) ans+=2*sum[n/p[i]]-1;
    		printf("%lld
    ",ans);
    		return 0;
    	}
    }
    signed main(){return yspm::main();}
    
  • 相关阅读:
    Reactor系列(四)subscribe订阅
    Reactor系列(三)创建Flux,Mono(续)
    Reactor系列(二)Flux Mono创建
    Reactor系列(一)基本概念
    Stream系列(十五)File方法使用
    Stream系列(十四)parallet方法使用
    OpenCV二值化、归一化操作
    C# 队列
    linux shell脚本程序路径作为变量
    C++中头文件(.h)和源文件(.cpp)都应该写些什么
  • 原文地址:https://www.cnblogs.com/yspm/p/12266238.html
Copyright © 2011-2022 走看看