标签:
hdu 1695 莫比乌斯反演给出a,b,c,d,k, 求满足a <= x <= b && c <= y <= d && gcd(x,y)=k 的数对(x,y)的对数。a=c=1; 0 < b,c <= 1e5; (n1,n2) 和 (n2,n1) 算为同种情况其实是求满足1 <= x <= b/k && 1 <= y <= d/k && gcd(x,y)=1 的 数对(x,y)的对数。#include <iostream> #include <algorithm> #include <string.h> #include <cstdio> #include <cmath> using namespace std; const int maxn=1000005; bool check[maxn]; int mu[maxn]; int prime[maxn]; void Moblus() { memset(check,false,sizeof(check)); int tot=0; mu[1]=1; for(int i=2; i<maxn; i++) { if(!check[i]) { prime[tot++]=i; mu[i]=-1; } for(int j=0; j<tot; j++) { if(i * prime[j]>=maxn)break; check[i*prime[j]]=true; mu[i*prime[j]]=-mu[i]; if(i%prime[j] == 0) { mu[i*prime[j]]=0; break; } } } } int main() { Moblus(); int a,b,c,d,k; int cas; scanf("%d",&cas); for(int cc=1; cc<=cas; cc++) { scanf("%d%d%d%d%d",&a,&b,&c,&d,&k); if(k==0) { printf("Case %d: 0\n",cc); continue; } b/=k; d/=k; if(b>d)swap(d,b); long long ans1=0; for(int i=1; i<=b; i++) ans1+=(long long )mu[i]*(b/i)*(d/i); long long ans2=0; for(int i=1; i<=b; i++) ans2+=(long long )mu[i]*(b/i)*(b/i); ans1-=ans2/2; printf("Case %d: %I64d\n",cc,ans1); } return 0; }
标签:
原文地址:http://www.cnblogs.com/Opaser/p/4797112.html