1. 程式人生 > >ZAP-Queries【POI2007】【莫比烏斯反演】

ZAP-Queries【POI2007】【莫比烏斯反演】

傳送門:https://www.luogu.org/problemnew/show/P3455

太經典了,,模板往上套

我直接上個截圖吧,,打公式太麻煩

整除分塊也是常識,直接上啦

#include<bits/stdc++.h>
#define in read()
using namespace std;

inline int in{
    int cnt=0,f=1; char ch=0;
    while(!isdigit(ch)){
        ch=getchar();
        if(ch=='-')f=-1;
    }
    while(isdigit(ch)){
        cnt=cnt*10+ch-48;
        ch=getchar();
    }
    return cnt*f;
}
#define N 50003
int mu[N],prim[N],cnt,vis[N];
long long sum[N];
inline void mumu(int n){
    mu[1]=1;
    for(register int i=2;i<=n;i++){
        if(!vis[i]){
            prim[++cnt]=i;
            mu[i]=-1;
        }
        for(register int j=1;j<=cnt&&prim[j]*i<=n;j++){
            vis[prim[j]*i]=1;
            if(i%prim[j]==0)break;
            else mu[prim[j]*i]=-mu[i];
        }
    }
    for(register int i=1;i<=n;i++)sum[i]=sum[i-1]+(long long)mu[i];
}int a,b,c,d,k;
inline long long query(int a,int b){
    if(a>b)swap(a,b);long long ans=0;
    for(register int l=1,r;l<=a;l=r+1){
        r=min(a/(a/l),b/(b/l));
        ans+=(1ll*a/(1ll*l*k))*(1ll*b/(1ll*l*k))*(sum[r]-sum[l-1]); 
    }
    return ans;
}
int main(){
    int t=in;mumu(N);
    while(t--){
        a=in;b=in;k=in;
        printf("%lld\n",query(a,b));
    }
    return 0;
}