码迷,mamicode.com
首页 > 其他好文 > 详细

YY的GCD(bzoj 2820)

时间:2017-03-09 00:33:07      阅读:133      评论:0      收藏:0      [点我收藏+]

标签:gcd   inpu   efi   printf   input   for   sam   output   blog   

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

 

盗图来自:http://blog.csdn.net/z690933166/article/details/11896565

技术分享

#include<cstdio>
#include<iostream>
#define N 10000010
#define lon long long
using namespace std;
int mul[N],prime[N],num,g[N],sum[N],f[N];
lon ans,n,m;
void get_prime(){
    mul[1]=1;
    for(int i=2;i<N;i++){
        if(!f[i]) prime[++num]=i,mul[i]=-1,g[i]=1;
        for(int j=1;j<=num&&i*prime[j]<N;j++){
            f[i*prime[j]]=1;
            if(i%prime[j]) mul[i*prime[j]]=-mul[i],g[i*prime[j]]=mul[i]-g[i];
            else {
                mul[i*prime[j]]=0;g[i*prime[j]]=mul[i];break;
            }
        }
    }
    for(int i=1;i<N;i++) sum[i]=sum[i-1]+g[i];
}
int main(){
    get_prime();
    int T;scanf("%d",&T);
    while(T--){
        scanf("%lld%lld",&n,&m);
        if(n>m) swap(n,m);
        ans=0;
        for(lon i=1,last=0;i<=n;i=last+1){
            last=min(n/(n/i),m/(m/i));
            ans+=(n/i)*(m/i)*(sum[last]-sum[i-1]);
        }
        printf("%lld\n",ans);
    }
    return 0;
}

 

YY的GCD(bzoj 2820)

标签:gcd   inpu   efi   printf   input   for   sam   output   blog   

原文地址:http://www.cnblogs.com/harden/p/6523375.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!