【Luogu】P2522Problemb(莫比乌斯反演)
同Zip—Queries,但是用到容斥原理
设f(n,m)是(x,y)的对数,其中1<=x<=n,1<=y<=m
则有f(n,m)-f(a-1,n)-f(b-1,m)+f(a-1,b-1)就是(x,y)的对数,其中a<=x<=n,b<=y<=m
然后就不多说啦
放代码
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<cctype> using namespace std; inline long long read(){ long long num=0,f=1; char ch=getchar(); while(!isdigit(ch)){ if(ch=='-') f=-1; ch=getchar(); } while(isdigit(ch)){ num=num*10+ch-'0'; ch=getchar(); } return num*f; } long long miu[100200]; long long prime[100200],tot; bool f[100200]; inline long long calc(long long n,long long m){ long long x=1,top=min(n,m),ans=0; while(x<=top){ long long y=min(n/(n/x),m/(m/x)); ans+=(miu[y]-miu[x-1])*(n/x)*(m/x); x=y+1; } return ans; } int main(){ miu[1]=1; for(int i=2;i<=100000;++i){ if(!f[i]){ prime[++tot]=i; miu[i]=-1; } for(int j=1;j<=tot&&(long long)i*prime[j]<=100000;++j){ f[(long long)i*prime[j]]=1; if(i%prime[j]) miu[(long long)i*prime[j]]=-miu[i]; else break; } } for(int i=1;i<=100000;++i) miu[i]+=miu[i-1]; int T=read(); while(T--){ long long a=read(),b=read(),c=read(),d=read(),e=read(); printf("%lld\n",calc(b/e,d/e)-calc((a-1)/e,d/e)-calc((c-1)/e,b/e)+calc((a-1)/e,(c-1)/e)); } return 0; }