【BZOJ2301】【HAOI2011】Problem B
题面
https://www.luogu.org/problem/P2522
题解
$Möbius\ inversion$的第一题,作为新的开始。
话说我们通常使用的式子是$$g(x)=\sum_{x|d}{f(d)} \Leftrightarrow f(x)=\sum_{i \ge 1}{\mu(i) g(i)}$$.
是一个相当明科但是很好理解的式子(卷积变点乘)我晕了,这么重要的式子竟然在《具体数学》上没有提到。。。
#include<cstdio> #include<cstring> #include<iostream> #define ri register int #define N 50500 #define LL long long using namespace std; inline int read() { int ret=0,f=0; char ch=getchar(); while (ch<'0' || ch>'9') f|=(ch=='-'),ch=getchar(); while (ch>='0' && ch<='9') ret=(ret<<1)+(ret<<3)+(ch^48),ch=getchar(); return f?-ret:ret; } int mu[N],cnt,f[N]; int prime[N]; void getmu() { mu[1]=1; for (ri i=2;i<N;i++) { if (!f[i]) { prime[++cnt]=i; mu[i]=-1; } for (ri j=1;i*prime[j]<N;j++) { f[i*prime[j]]=1; if (i%prime[j]) { mu[i*prime[j]]=-mu[i]; } else { mu[i*prime[j]]=0; break; } } } for (ri i=1;i<N;i++) mu[i]+=mu[i-1]; } LL calc(int k,int n,int m) { n/=k; m/=k; LL ret=0; for (ri i=1,j;i<=min(n,m);i=j+1) { j=min(n/(n/i),m/(m/i)); ret+=(mu[j]-mu[i-1])*1LL*(n/i)*1LL*(m/i); } return ret; } int main() { getmu(); int T=read(); while (T--) { int a=read(),b=read(),c=read(),d=read(),k=read(); cout<<calc(k,b,d)-calc(k,a-1,d)-calc(k,b,c-1)+calc(k,a-1,c-1)<<endl; } return 0; }