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

    Description###

    神犇YY虐完数论后给傻×kAc出了一题

    给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少对

    kAc这种傻×必然不会了,于是向你来请教……

    多组输入

    Input###

    第一行一个整数T 表述数据组数

    接下来T行,每行两个正整数,表示N, M

    Output###

    T行,每行一个整数表示第i组数据的结果

    Sample Input###

    2
    10 10
    100 100

    Sample Output###

    30
    2791

    HINT###

    T = 10000
    N, M <= 10000000


    想法##

    Orz PoPoQQQ大神……
    若枚举每个质数 (p)

    [egin{equation*} egin{aligned} ans&= sumlimits_p sumlimits_{p|k} mu(frac{k}{p}) F(k) \ &= sumlimits_p sumlimits_{d=1}^{frac{min(n,m)}{p}} mu(d) lfloor frac{n}{dp} floor lfloor frac{m}{dp} floor end{aligned} end{equation*} ]

    (T=dp)

    [ans=sumlimits_{T=2}^{min(n,m)} lfloor frac{n}{T} floor lfloor frac{m}{T} floor sumlimits_{p|T 且p为质数} mu(frac{T}{p}) ]

    预处理计算每个数 (T)(sumlimits_{p|T 且p为质数} mu(frac{T}{p})) 及其前缀和
    用每个质数把自己的倍数筛一遍就行了。


    代码##

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    typedef long long ll;
    const int N = 10000005;
    
    int mu[N];
    ll sum[N];
    int prime[N],pnum,p[N];
    int getmu(){
        mu[1]=1;
        for(int i=2;i<N;i++) p[i]=1;
        for(int i=2;i<N;i++){
            if(p[i]) {
                prime[pnum++]=i;
                mu[i]=-1;        
            }
            for(int j=0;j<pnum && (ll)prime[j]*i<N;j++){
                p[i*prime[j]]=0;
                if(i%prime[j]==0) {
                    mu[i*prime[j]]=0;
                    break;
                }
                mu[i*prime[j]]=-mu[i];
            }
        }
        for(int i=0;i<pnum;i++)
            for(int j=1;(ll)j*prime[i]<N;j++)
                sum[j*prime[i]]+=mu[j];
        sum[1]=0;
        for(int i=2;i<N;i++) sum[i]+=sum[i-1];
    }
    
    int n,m,T;
    
    int main()
    {
        getmu();
        scanf("%d",&T);
        
        ll ans;
        while(T--){
            scanf("%d%d",&n,&m);
            ans=0;
            for(int l=2,r;l<=min(n,m);l=r+1){
                r=min(n/(n/l),m/(m/l));
                ans+=(sum[r]-sum[l-1])*(n/l)*(m/l);
            }
            printf("%lld
    ",ans);
        }
        
        return 0;    
    }
    
    既然选择了远方,便只顾风雨兼程
  • 相关阅读:
    RocketMQ(4.8.0)——Broker读写分离机制
    RocketMQ(4.8.0)——Broker消息存储机制
    RocketMQ(4.8.0)——Broker 概述、启动和停止流程
    RocketMQ(4.8.0)——RocketMQ的路由原理
    RocketMQ(4.8.0)——Namesrv 服务
    RocketMQ(4.8.0)——RocketMQ部署拓扑和部署实践
    RocketMQ(4.8.0)——RocketMQ体系架构
    RocketMQ(4.8.0)——消费者最佳实践
    Java丨时间判断谁前谁后
    MySQL丨分页查询
  • 原文地址:https://www.cnblogs.com/lindalee/p/8504303.html
Copyright © 2011-2022 走看看