[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

同[bzoj2820] YY的GCD

注意一点,由于只有一组数据,可以用多少筛多少,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;
}
posted @ 2018-12-06 16:02  Hyscere  阅读(158)  评论(0编辑  收藏  举报