BZOJ 2818GCD

转载注明出处:http://www.cnblogs.com/radioteletscope/p/7142762.html

题面:

2818: Gcd

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 5345  Solved: 2400
[Submit][Status][Discuss]

Description

给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的
数对(x,y)有多少对.

Input

一个整数N

Output

如题

Sample Input

4

Sample Output

4

HINT

hint

对于样例(2,2),(2,4),(3,3),(4,2)

1<=N<=10^7

令$f[i]=\sum_{d|T}^{} \mu(\frac{T}{d})$

只需线性筛出,再分块处理询问。

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 #define LL long long
 5 const int maxn=10000001;
 6 int mu[maxn+10],prime[maxn+10],g[maxn+10];
 7 int s[maxn+10];
 8 bool book[maxn+10];
 9 int T,n,cnt;
10 void ss()
11 {
12     mu[1]=1;
13     for(int i=2;i<=maxn;i++)
14     {
15         if(!book[i])
16         {
17             prime[++cnt]=i; 
18             mu[i]=-1;
19             g[i]=1;
20         }
21         for(int j=1;j<=cnt&&i*prime[j]<=maxn;j++)
22         {
23             book[i*prime[j]]=true;
24             if(i%prime[j])
25                 mu[i*prime[j]]=-mu[i],g[i*prime[j]]=mu[i]-g[i];
26             else   
27             {
28                 mu[i*prime[j]]=0;
29                 g[i*prime[j]]=mu[i];
30                 break;
31             }
32         }
33     }
34     s[0]=0;
35     for(int i=1;i<=maxn;i++)
36         s[i]=s[i-1]+g[i];
37 }
38 LL caculate()
39 {
40     LL ans=0,last;
41     for(int i=1;i<=n;i=last+1)
42     {
43         last=n/(n/i);
44         ans+=(LL)(s[last]-s[i-1])*(n/i)*(n/i);
45     }
46     return ans;
47 }
48 int main()
49 {
50     ss();
51     scanf("%d",&n);
52     printf("%lld\n",caculate());
53 }
BZOJ 2818

 

posted @ 2017-07-09 20:35  avancent  阅读(195)  评论(0编辑  收藏  举报