[POI2007] ZAP-Queries (莫比乌斯反演)

Code

#include<bits/stdc++.h>
#define lol long long
#define il inline
#define rg register
#define Min(a,b) (a)<(b)?(a):(b)
#define Max(a,b) (a)>(b)?(a):(b)

using namespace std;

const int N=5e4+10;

void in(int &ans)
{
    ans=0; int f=1; char i=getchar();
    while(i<'0' || i>'9') {if(i=='-') f=-1; i=getchar();}
    while(i>='0' && i<='9') ans=(ans<<1)+(ans<<3)+i-'0', i=getchar();
    ans*=f;
}

int n,m,d,tot,ans,T;
int mu[N],sum[N],prime[N];
bool vis[N];

il void get_mu() {
    mu[1]=1;
    for(int i=2;i<=N-10;i++) {
        if(!vis[i]) prime[++tot]=i,mu[i]=-1;
        for(int j=1;j<=tot && prime[j]*i<=N-10;j++) {
            vis[i*prime[j]]=1;
            if(i%prime[j]==0) break;
            else mu[i*prime[j]]=-mu[i];
        }
    }
    for(int i=1;i<=N-10;i++) sum[i]=sum[i-1]+mu[i];
}

int main()
{
    in(T); get_mu();
    while(T--) {
        in(n),in(m),in(d); n/=d,m/=d,ans=0;
        for(rg int i=1,pos,p=Min(n,m);i<=p;i=pos+1) {
            pos=Min(n/(n/i),m/(m/i));
            ans+=(sum[pos]-sum[i-1])*(n/i)*(m/i);
        }
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/real-l/p/9628232.html