题解:
莫比乌斯反演
再加上一个分块
然后和上一题差不多了
代码:
#include<cstdio> #include<cmath> #include<algorithm> #include<cstring> using namespace std; typedef long long ll; const int N=100005; ll ans1,ans2; int sum[N],a,b,x,y,z,tot,T,cnt,miu[N],flag[N],p[N]; void init() { miu[1]=1; sum[1]=1; for (int i=2;i<N;i++) { if (!flag[i]) { miu[i]=-1; p[++tot]=i; } for (int j=1;j<=tot;j++) { int k=p[j]*i; if (k>=N)break; flag[k]=1; if (i%p[j]==0) { miu[k]=0; break; } miu[k]-=miu[i]; } } for (int i=1;i<N;i++)sum[i]=sum[i-1]+miu[i]; } ll find(int x,int y) { if (x>y)swap(x,y); ll ans=0;int j; for (int i=1;i<=x;i=j+1) { j=min(x/(x/i),y/(y/i)); ans+=(ll)(sum[j]-sum[i-1])*(x/i)*(y/i); } return ans; } int main() { scanf("%d",&T); init(); while (T--) { ans1=ans2=0; scanf("%d%d%d%d%d",&a,&x,&b,&y,&z); x/=z;y/=z;a=(a-1)/z;b=(b-1)/z; ans1=find(x,y)-find(a,y)-find(x,b)+find(a,b); printf("%lld\n",ans1); } }