先预处理莫比乌斯函数,再分块求
不会用公式编辑TAT,直接贴题解吧。。
从结论来看貌似也能用容斥原理?
1 #include<bits/stdc++.h> 2 #define inc(i,l,r) for(int i=l;i<=r;i++) 3 #define dec(i,l,r) for(int i=l;i>=r;i--) 4 #define link(x) for(edge *j=h[x];j;j=j->next) 5 #define mem(a) memset(a,0,sizeof(a)) 6 #define inf 1e9 7 #define ll long long 8 #define succ(x) (1<<x) 9 #define NM 50000+5 10 using namespace std; 11 int read(){ 12 int x=0,f=1;char ch=getchar(); 13 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 14 while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); 15 return x*f; 16 } 17 int mu[NM],sum[NM],a,b,c,d,k,T,p[NM],tot; 18 bool check[NM]; 19 int slove(int x,int y){ 20 int t,ans=0; 21 if((x/=k)>(y/=k))swap(x,y); 22 for(int i=1;i<=x;i=t+1){ 23 t=min(x/(x/i),y/(y/i)); 24 if(t>x)t=x; 25 ans+=(sum[t]-sum[i-1])*(x/i)*(y/i); 26 } 27 return ans; 28 } 29 int main(){ 30 freopen("data.in","r",stdin); 31 T=read(); 32 sum[1]=mu[1]=1; 33 inc(i,2,NM-5){ 34 if(!check[i]){ 35 p[++tot]=i; 36 mu[i]=-1; 37 } 38 sum[i]=sum[i-1]+mu[i]; 39 inc(j,1,tot){ 40 if(i*p[j]>NM-5)break; 41 check[i*p[j]]=true; 42 if(i%p[j])mu[i*p[j]]=-mu[i]; 43 else break; 44 } 45 } 46 // inc(i,1,10)printf("%d ",mu[i]);printf("\n"); 47 while(T--){ 48 a=read();b=read();c=read();d=read();k=read(); 49 printf("%d\n",slove(b,d)-slove(a-1,d)-slove(b,c-1)+slove(a-1,c-1)); 50 } 51 return 0; 52 }