【bzoj2820】YY的GCD 莫比乌斯反演

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

 

题解:

根据F的定义,因为其不是积性函数,所以不可以O(n)

处理,那么就是暴力去处理,先处理处μ,然后再解决

最后分块搞

 1 #include<cstring>
 2 #include<cmath>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cstdio>
 6 
 7 #define ll long long
 8 #define N 10000007
 9 #define lim 10000000
10 using namespace std;
11 inline int read()
12 {
13     int x=0,f=1;char ch=getchar();
14     while(ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();}
15     while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
16     return x*f;
17 }
18 
19 int n;
20 int cnt,flag[N],pri[N],mu[N];
21 ll f[N];
22 
23 void get_mu()
24 {
25     mu[1]=1;
26     for (int i=2;i<=lim;i++)
27     {
28         if (!flag[i])pri[++cnt]=i,mu[i]=-1;
29         for (int j=1;j<=cnt&&pri[j]*i<=lim;j++)
30         {
31             flag[pri[j]*i]=true;
32             if (i%pri[j]==0)
33             {
34                 mu[i*pri[j]]=0;
35                 break;
36             }
37             else mu[i*pri[j]]=-mu[i];
38         }
39     }
40     for (int i=1;i<=cnt;i++)
41     {
42         int p=pri[i];
43         for (int j=1;j*p<=lim;j++)
44             f[j*p]+=mu[j];
45     }
46     for (int i=1;i<=lim;i++)
47         f[i]+=f[i-1];
48 }
49 int main()
50 {
51     get_mu();
52     int T=read();
53     while(T--)
54     {
55         ll ans=0;
56         int n=read(),m=read();
57         if (n>m)swap(n,m);
58         for (int i=1,last;i<=n;i=last+1)
59         {
60             last=min(n/(n/i),m/(m/i));
61             ans+=(f[last]-f[i-1])*(n/i)*(m/i);
62         }
63         printf("%lld\n",ans);
64     }
65 }

 

posted @ 2018-01-12 19:06  Kaiser-  阅读(140)  评论(0编辑  收藏  举报