[bzoj2818] Gcd
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
solution
注意一点,由于只有一组数据,可以用多少筛多少,bzoj卡常大法。其实只是因为我被卡T了
加个优化10sTLE变3s。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
void read(int &x) {
x=0;int f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
}
void print(int x) {
if(x<0) putchar('-'),x=-x;
if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');}
#define maxn 10000011
int mu[maxn+10],sum[maxn+10],pri[maxn+10],tot,vis[maxn+10],n,m;
#undef maxn
int maxn;
void time() {cerr << (double) clock()/CLOCKS_PER_SEC << endl;}
void sieve() {
mu[1]=1;
for(int i=2;i<maxn;i++) {
if(!vis[i]) pri[++tot]=i,mu[i]=-1;
for(int j=1;j<=tot&&i*pri[j]<maxn;j++) {
vis[i*pri[j]]=1;
if(!(i%pri[j])) {mu[i*pri[j]]=0;break;}
mu[i*pri[j]]=-mu[i];
}
}//time();write(tot);
for(int i=1;i<=tot;i++)
for(int j=1;j*pri[i]<maxn;j++) sum[j*pri[i]]+=mu[j];
for(int i=1;i<maxn;i++) sum[i]=sum[i]+sum[i-1];
//time();
}
signed main() {//int asd;read(asd);
//for(int i=1;i<=10;i++) write(sum[i]);
//while(asd--) {
read(n);maxn = n+1;
sieve();
int T=1;ll ans=0;
while(T<=n) {
int pre=T;T=n/(n/T);
ans+=1ll*(n/pre)*(n/pre)*(sum[T]-sum[pre-1]);
T++;
}
printf("%lld\n",ans);
//}
return 0;
}