【題解】Luogu P4450 雙親數
阿新 • • 發佈:2018-12-17
原題傳送門
這題需要運用莫比烏斯反演(懵逼鎢絲繁衍)
設F(t)表示滿足gcd(x,y)%t=0的數對個數,f(t)表示滿足gcd(x,y)=t的數對個數,實際上答案就是f(d)
這就滿足莫比烏斯反演的關係式了
顯然我們珂以得知F(t)=(b/t)*(d/t)
我們根據反演的第二個公式便珂以得出
\[f(d)=\sum_{n|d}\mu(\frac{d}{n})F(d)\]
在用下整除分塊就過了
#include <bits/stdc++.h> #define N 1000005 #define ll long long #define getchar nc using namespace std; inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; } inline int read() { register int x=0,f=1;register char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); return x*f; } inline void write(register ll x) { if(!x)putchar('0');if(x<0)x=-x,putchar('-'); static int sta[20];register int tot=0; while(x)sta[tot++]=x%10,x/=10; while(tot)putchar(sta[--tot]+48); } inline int Min(register int a,register int b) { return a<b?a:b; } int miu[N],v[N]; ll sum[N]; int main() { for(register int i=1;i<=N;++i) miu[i]=1,v[i]=0; for(register int i=2;i<=N;++i) { if(v[i]) continue; miu[i]=-1; for(register int j=i<<1;j<=N;j+=i) { v[j]=1; if((j/i)%i==0) miu[j]=0; else miu[j]*=-1; } } for(register int i=1;i<=N;++i) sum[i]=sum[i-1]+miu[i]; int a=read(),b=read(),k=read(); int maxround=Min(a/k,b/k); ll ans=0; for(register int l=1,r;l<=maxround;l=r+1) { r=Min((a/k)/((a/k)/l),(b/k)/((b/k)/l)); ans+=(ll)((a/k)/l)*((b/k)/l)*(sum[r]-sum[l-1]); } write(ans); return 0; }