zoukankan      html  css  js  c++  java
  • 洛谷 P2257 YY的GCD

    洛谷 P2257 YY的GCD



    $ solution: $

    这道题完全跟[POI2007]ZAP-Queries (莫比乌斯反演+整除分块) 用的一个套路。

    我们可以列出答案就是要我们求:

    $ ans=sum_{pin prime}sum_{i=1}^{n}{sum_{j=1}^{m}{[gcd(i,j)==p]}} $

    我们发现后面那一部分( $ sum_{i=1}^{n}{sum_{j=1}^{m}{[gcd(i,j)==p]}} $ )可以套路的莫比乌斯反演:

    $ ans=sum_{pin prime}sum_{i=1}^{frac{n}{p}}{sum_{j=1}^{frac{m}{p}}{[gcd(i,j)==1]}} $

    $ ans=sum_{pin prime}sum_{i=1}^{frac{n}{p}}{sum_{j=1}^{frac{m}{p}}{sum_{k|gcd(i,j)}{mu(k)}}} $

    $ ans=sum_{pin prime}sum_{k}^{min(n,m)}{mu(k)}{sum_{i=1}^{frac{n}{p}}{sum_{j=1}^{frac{m}{p}}{[k|gcd(i,j)]}}} $

    $ ans=sum_{pin prime}sum_{k}^{min(n,m)}{mu(k) imes lfloor frac{n}{p imes k} floor imes lfloor frac{m}{p imes k} floor} $

    我们发现后面那两个东西有点麻烦,我们想办法让它变成常数项:

    设: $ T=p imes k $

    $ ans=sum_{t=1}^{min(n,m)} lfloor frac{n}{T} floor imes lfloor frac{m}{T} floor sum_{p|T,pin prime} mu{frac{T}{p}} $

    然后我们发现后面那一部分( $ sum_{p|T,pin prime} mu{frac{T}{p}} $ )可以预处理,然后我们在前面用整除分块,这样就可以每次只用 $ log(min(n,m)) $ 的时间完成单个询问了!



    $ code: $

    #include<iostream>
    #include<cstdio>
    #include<iomanip>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<ctime>
    #include<cmath>
    #include<vector>
    #include<queue>
    #include<map>
    #include<set>
    
    #define ll long long
    #define db double
    #define inf 0x7fffffff
    #define rg register int
    
    using namespace std;
    
    const int N=1e7;
    
    ll ans;
    int n,m,t;
    int pr[10000005];
    int mu[10000005];
    int sum[10000005];
    bool zhi[10000005];
    
    inline int qr(){
        register char ch; register bool sign=0; rg res=0;
        while(!isdigit(ch=getchar())) if(ch=='-')sign=1;
        while(isdigit(ch)) res=res*10+(ch^48),ch=getchar();
        return sign?-res:res;
    }
    
    inline void get_ready(){
        mu[1]=1; int t=0;
        for(rg i=2;i<=N;++i){
            if(!zhi[i])pr[++t]=i,mu[i]=-1;
            for(rg j=1;j<=t;++j){
                if(i*pr[j]>N)break;
                zhi[i*pr[j]]=1;
                if(!(i%pr[j]))break;
                mu[i*pr[j]]=-mu[i];
            }
        }
        for(rg i=1;i<=t;++i)
            for(rg j=1;j*pr[i]<=N;++j)
                sum[j*pr[i]]+=mu[j];
        for(rg i=1;i<=N;++i) sum[i]+=sum[i-1];
    }
    
    int main(){
        //freopen(".in","r",stdin);
        //freopen(".out","w",stdout);
        t=qr(); get_ready();
        while(t--){ ans=0;
            n=qr(); m=qr();
            rg x=min(n,m),l,r;
            for(l=1;l<=x;l=r+1){
                r=min(n/(n/l),m/(m/l));
                ans+=(ll)(n/l)*(m/l)*(sum[r]-sum[l-1]);
            }printf("%lld
    ",ans);
        }
        return 0;
    }
    
    
  • 相关阅读:
    [学习笔记] 网络最大流的HLPP算法
    [学习笔记] LCT 初步
    js中函数的原型及继承
    关于js中函数的一点总结
    关于css实现水平及垂直居中的方法记录
    js基础总结03 --操作数组
    近期学习es6后对变量提升及let和const的一点思考
    用css和js实现侧边菜单栏点击和鼠标滑动特效
    用css或js实现文本输入框的特效
    Jmeter怎样打印日志
  • 原文地址:https://www.cnblogs.com/812-xiao-wen/p/10729156.html
Copyright © 2011-2022 走看看