Luogu 1447 - [NOI2010]能量采集 (莫比乌斯反演)

Luogu 1447 - [NOI2010]能量采集


题意

给定\(n,m\),在坐标系\((0,0)\) 位置有一个能量采集器

可行范围为\(n\times m\)内的所有整数点(不包括坐标轴上)

pic_origin

开采每个整数点会造成\(1\)能量损失

对于每个点\((x,y)\),如果\((0,0)\)与其连线上存在着\(cnt\)个其它整数点,那么它的能量损失将会增加\(2\times cnt\)

即对于每个点,能量损失为\(2\times cnt_{(x,y)}+1\)

\(n\times m\)范围内所有点的能量损失之和,即求

\[\sum_{i=1}^n\sum_{j=1}^m2\times cnt_{(x,y)}+1 \]


限制

\(Case=1,\ 1\leq n,m\leq 10^5\)




思路

根据题意(或据图可得)

每个点\((x,y)\)\((0,0)\)点连线上的其余整数点个数即为\(\gcd(x,y)-1\)

所以所求的答案即可转化为

\[\begin{align} &\sum_{i=1}^n\sum_{j=1}^m2\times (\gcd(i,j)-1)+1\\ =&\sum_{i=1}^n\sum_{j=1}^m2\times \gcd(i,j)-1\\ =&2\times \sum_{i=1}^n\sum_{j=1}^m(\gcd(i,j))-n\times m\\ =&2\times \sum_{d=1}^{\min(n,m)}d\times\sum_{i=1}^n\sum_{j=1}^m[\gcd(i,j)=d] -n\times m\\ =&2\times \sum_{d=1}^{\min(n,m)}d\times\sum_{i=1}^{\frac n d}\sum_{j=1}^{\frac m d}[\gcd(i,j)=1] -n\times m\\ =&2\times \sum_{d=1}^{\min(n,m)}d\times\sum_{i=1}^{\frac{\min(n,m)}{d}}\mu(i)\lfloor\frac{\lfloor\frac n d\rfloor}{i}\rfloor\lfloor\frac{\lfloor\frac m d\rfloor}{i}\rfloor -n\times m\\ \end{align} \]

直接套板子即可



代码

Case Max (15ms/1000ms)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=100000;

ll mu[N+50],prim[N+50];
bool vis[N+50];

void init(int n)
{
    memset(vis,false,sizeof vis);
    mu[1]=1;
    int p=0;
    for(int i=2;i<=n;i++)
    {
        if(!vis[i])
        {
            prim[p++]=i;
            mu[i]=-1;
        }
        for(int j=0;j<p;j++)
        {
            int k=i*prim[j];
            if(k>n)
                break;
            vis[k]=true;
            if(i%prim[j]==0)
            {
                mu[k]=0;
                break;
            }
            else
                mu[k]=-mu[i];
        }
    }
}

int main()
{
    init(N);
    int n,m;
    scanf("%d%d",&n,&m);
    ll ansd,ans=0;
    int mn=min(n,m);
    for(int d=1;d<=mn;d++)
    {
        int mnd=mn/d,a=n/d,b=m/d;
        ansd=0;
        for(int i=1;i<=mnd;i++)
            ansd+=mu[i]*(a/i)*(b/i);
        ans+=ansd*d;
    }
    printf("%lld\n",ans*2-1LL*n*m);
    
    return 0;
}

posted @ 2020-08-08 20:07  StelaYuri  阅读(130)  评论(0编辑  收藏  举报