码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-12-04 22:22:32      阅读:258      评论:0      收藏:0      [点我收藏+]

标签:swap   floor   math   include   printf   play   algo   space   mmu   

思路

和YY的GCD类似但是更加简单了
类似的推一波公式即可
\[ F(n)=\sum_{n|d}f(d) \]

\[ f(n)=\sum_{n|d}\mu(\frac{d}{n})F(d) \]

\[ F(d)=\lfloor\frac{n}{d}\rfloor\times\lfloor\frac{m}{d}\rfloor \]

\[ f(x)=\sum_{x|d}\mu(\frac{d}{x})\times\lfloor\frac{n}{d}\rfloor\times\lfloor\frac{m}{d}\rfloor \]

\[ f(x)=\sum_{t=1}^{\lfloor\frac{n}{x}\rfloor}\mu(t)\times\lfloor\frac{n}{x\times t}\rfloor\times\lfloor\frac{m}{x\times t}\rfloor \]
然后整除分块即可

代码

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int T,n,m,mu[51000],iprime[51000],isprime[51000],summu[51000],cnt,k;
void prime(int n){
    isprime[1]=true;
    mu[1]=1;
    for(int i=2;i<=n;i++){
        if(!isprime[i])
            iprime[++cnt]=i,mu[i]=-1;
        for(int j=1;j<=cnt&&iprime[j]*i<=n;j++){
            isprime[iprime[j]*i]=true;
            mu[iprime[j]*i]=-mu[i];
            if(i%iprime[j]==0){
                mu[iprime[j]*i]=0;
                break;
            }
        }
    }
    for(int i=1;i<=n;i++)
        summu[i]=summu[i-1]+mu[i];
}
long long f(int k){
    long long ans=0;
    for(int l=1,r;l<=min(n,m);l=r+1){
        r=min((n/(n/(l))),(m/(m/(l))));
        ans+=1LL*(summu[r]-summu[l-1])*(n/(l*k))*(m/(l*k));
        }
    return ans;
}
int main(){
    prime(50100);
    scanf("%d",&T);
    while(T--){
        scanf("%d %d %d",&n,&m,&k);
        if(n<m)
            swap(n,m);
        printf("%lld\n",f(k));
    }
    return 0;
}

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

标签:swap   floor   math   include   printf   play   algo   space   mmu   

原文地址:https://www.cnblogs.com/dreagonm/p/10066914.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!