zoukankan      html  css  js  c++  java
  • 「Luogu2257」YY的GCD

    「Luogu2257」YY的GCD

    蒟蒻的第一道莫反

    跟着题解推的式子,但还是记录一下过程吧

    本文可能在一定程度上存在谬误,请谨慎分析

    若发现文中有错误,如您愿意,恳请您向我指出,不胜感激


    problem

    Solution

    题目要求:

    [ans=sum_{i=1}^Nsum_{j=1}^M[gcd(i,j)in prime] ]

    (f(p)=sum_{i=1}^Nsum_{j=1}^M[gcd(i,j)=p](pin prime))

    再令(g(p)=sum_{i=1}^Nsum_{j=1}^M[p|gcd(i,j)](pin prime))

    于是有

    [g(n)=sum_{n|d}f(d) ]

    反演后可得

    [f(n)=sum_{n|d}mu(frac{d}{n})g(d) ]

    又知(g(d)=lfloorfrac{N}{d} floorlfloorfrac{M}{d} floor)

    于是有

    [ans=sum_{nin prime}f(n)=sum_{nin prime}sum_{n|d}mu (frac{d}{n})lfloorfrac{N}{d} floorlfloorfrac{M}{d} floor\=sum_{n|d}lfloorfrac{N}{d} floorlfloorfrac{M}{d} floorsum_{nin prime}mu(frac{d}{n})\=sum_{d=1}^{min(N,M)}lfloorfrac{N}{d} floorlfloorfrac{M}{d} floorsum_{n|d,nin prime}mu(frac{d}{n}) ]

    (sum(d)=sum_{n|d,nin prime}mu(frac{d}{n})),预处理(sum(d))

    那么答案即

    [ans=sum_{d=1}^{min(M,N)}lfloorfrac{N}{d} floorlfloorfrac{M}{d} floor sum(d) ]

    (sum sum(d))仍可以利用前缀和优化,(sumlfloorfrac{N}{d} floorlfloorfrac{M}{d} floor)利用整除分块优化,最终时间复杂度为(O(Tsqrt{min(N,M)}+k))(k)为预处理复杂度

    Code

    #include <cstdio>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #define maxn 10000005
    #define N 10000000
    using namespace std;
    typedef long long ll;
    
    template <typename T> void read(T &t)
    {
    	t=0;int f=0;char c=getchar();
    	while(!isdigit(c)){f|=c=='-';c=getchar();}
    	while(isdigit(c)){t=t*10+c-'0';c=getchar();}
    	if(f)t=-t;
    }
    
    int T;
    int n,m;
    int pri[maxn],pcnt,nop[maxn];
    int mu[maxn];
    ll sum[maxn],up;
    
    void GetPrime()
    {
    	nop[1]=1,mu[1]=1;
    	for(register int i=2;i<=N;++i)
    	{
    		if(!nop[i])pri[++pcnt]=i,mu[i]=-1; 
    		for(register int j=1;j<=pcnt && i*pri[j]<=N;++j)
    		{
    			nop[i*pri[j]]=1;
    			if(i%pri[j]==0)break;
    			else mu[i*pri[j]]=-mu[i];
    		}
    	}
    	for(register int i=1;i<=pcnt;++i)
    		for(register int j=1;pri[i]*j<=N;++j)
    			sum[pri[i]*j]+=mu[j];
    	for(register int i=1;i<=N;++i)
    		sum[i]+=sum[i-1];
    }
    
    ll Calc()
    {
    	ll re=0;
    	for(register int l=1,r;l<=up;l=r+1)
    	{
    		r=min(n/(n/l),m/(m/l));
    		re+=1ll*(n/l)*(m/l)*(sum[r]-sum[l-1]);
    	}
    	return re;
    }
    
    int main()
    {
    	read(T);
    	GetPrime();
    	while(T--)
    	{
    		read(n),read(m);
    		up=min(n,m);
    		printf("%lld
    ",Calc());
    	}
    	return 0;
    }
    
  • 相关阅读:
    selenium自动登陆
    解决selenium.common.exceptions.InvalidArgumentException: Message: invalid argument: invalid 'expiry'
    python selenium 自动登陆
    Python操作CSV和Excel
    scrapy Request方法
    from lxml import etree报错
    python文件管道 下载图集
    scrapy基本爬虫,采集多页
    《全唐诗》与《全宋词》
    [转]一个程序员的哲学思考(关于编程、关于人生)
  • 原文地址:https://www.cnblogs.com/lizbaka/p/10508947.html
Copyright © 2011-2022 走看看