• 题解「Luogu6055 [RC-02] GCD」


    题目要求:

    [ ext{Ans}=sum_{i=1}^Nsum_{j=1}^Nsum_{p=1}^{lfloorfrac{N}{j} floor}sum_{q=1}^{lfloorfrac{N}{j} floor}[{ m{gcd}}(i,j)=1][{ m{gcd}}(p,q)=1] ]

    式中 (p,q) 的枚举范围均只与 (j) 有关,根据这个下取整的形式,想到下面这个常用的式子:

    [sum_{i=1}^Nsum_{j=1}^N[{ m{gcd}}(i,j)=k]=sum_{k=1}^Nsum_{i=1}^{lfloorfrac{N}{k} floor}sum_{j=1}^{lfloorfrac{N}{k} floor}[{ m{gcd}}(i,j)=1] ]

    所以我们用 (p,q) 代替 (jp,jq) ,式子变为:

    [egin{align} &sum_{i=1}^Nsum_{p=1}^{N}sum_{q=1}^{N}[{ m{gcd}}(i,j)=1][{ m{gcd}}(p,q)=j]\ &=sum_{i=1}^Nsum_{p=1}^{N}sum_{q=1}^{N}[{ m{gcd}}(i,{ m{gcd}}(p,q))=1]\ &=sum_{i=1}^Nsum_{p=1}^{N}sum_{q=1}^{N}[{ m{gcd}}(i,p,q)=1]\ &=sum_{i=1}^Nsum_{p=1}^{N}sum_{q=1}^{N}sum_{d|i,d|p,d|q}mu(d)\ &=sum_{d=1}^Nmu(d)lfloorfrac{N}{d} floor^3 end{align} ]

    杜教筛+整除分块即可。


    ( ext{Code}:)

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <map>
    #define maxn 10000005
    #define Rint register int
    #define INF 0x3f3f3f3f
    using namespace std;
    typedef long long lxl;
    const lxl mod=998244353;
    
    template <typename T>
    inline T read()
    {
    	T x=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    	return x*f;
    }
    
    int prime[maxn],cnt;
    bool flag[maxn];
    lxl mu[maxn];
    
    inline void sieve()
    {
    	mu[1]=1;
    	for(int i=2;i<maxn;++i)
    	{
    		if(!flag[i]) prime[++cnt]=i,mu[i]=-1;
    		for(int j=1;j<=cnt&&i*prime[j]<maxn;++j)
    		{
    			flag[i*prime[j]]=true;
    			if(!(i%prime[j])) break;
    			mu[i*prime[j]]=-mu[i];
    		}
    	}
    	for(int i=1;i<maxn;++i)
    		mu[i]+=mu[i-1];
    }
    
    map<int,lxl> mp;
    
    inline lxl GetS(int n)
    {
    	if(n<maxn) return mu[n];
    	if(mp[n]) return mp[n];
    	lxl res=1;
    	for(int l=2,r;l<=n;l=r+1)
    	{
    		r=n/(n/l);
    		res=(res-(r-l+1)*GetS(n/l)%mod+mod)%mod;
    	}
    	return mp[n]=res;
    }
    
    inline lxl calcu(lxl N)
    {
    	lxl res=0;
    	for(lxl l=1,r;l<=N;l=r+1)
    	{
    		r=N/(N/l);
    		lxl d=N/l;d=d*d%mod*d%mod;
    		res=(res+(GetS(r)-GetS(l-1)+mod)%mod*d%mod)%mod;
    	}
    	return res;
    }
    
    int main()
    {
    	// freopen("P6055.in","r",stdin);
    	sieve();
    	lxl N=read<lxl >();
    	printf("%lld
    ",calcu(N));
    	return 0;
    }
    
    
  • 相关阅读:
    halcon7月license
    软设考试成绩查询结果
    Halcon自学笔记
    Window_Store
    Windows_Store之2048
    基于C#开发的2048
    MVC+EF+EasyUI实现CRUD
    ASP.NET MVC Model验证总结
    浙江省三级数据库考试
    基于C#的短信发送
  • 原文地址:https://www.cnblogs.com/syc233/p/13547536.html
Copyright © 2020-2023  润新知