BZOJ2820:YY的GCD——题解

http://www.lydsy.com/JudgeOnline/problem.php?id=2820

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

————————————————————————

看hzw的博客吧,他讲的蛮清楚的……

我主要是没有可以写数学公式的东西……

http://hzwer.com/6142.html

#include<cstdio>
#include<queue>
#include<cctype>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=10000010;
int miu[N],su[N],sum[N];
ll f[N];
bool he[N];
void Euler(int n){
    int tot=0;
    miu[1]=1;    
    for(int i=2;i<=n;i++){    
    if(!he[i]){   
        su[++tot]=i;    
        miu[i]=-1;
    }    
    for(int j=1;j<=tot;j++){    
        if(i*su[j]>=n)break;    
        he[i*su[j]]=1;   
        if(i%su[j]==0){    
        miu[i*su[j]]=0;break;    
        }    
        else miu[i*su[j]]=-miu[i];  
    }
    }
    for(int i=1;i<=tot;i++){
    int p=su[i];
    for(int j=1;j*p<=n;j++)f[j*p]+=miu[j];
    }
    for(int i=1;i<=n;i++)f[i]+=f[i-1];
    return;
}
int main(){
    Euler(10000001);
    int t;
    scanf("%d",&t);
    while(t--){
    int a,b;ll ans=0;
    scanf("%d%d",&a,&b);
    if(a>b)swap(a,b);
    for(int i=1,j;i<=a;i=j+1){
        j=min(a/(a/i),b/(b/i));
        ans+=(f[j]-f[i-1])*(a/i)*(b/i);
    }
    printf("%lld\n",ans);
    }
    return 0;
}

 

posted @ 2018-01-04 17:28  luyouqi233  阅读(138)  评论(0编辑  收藏  举报