• 洛谷P3327 [SDOI2015]约数个数和(莫比乌斯反演)


    题目描述

    设d(x)为x的约数个数,给定N、M,求 sum^N_{i=1}sum^M_{j=1}d(ij)i=1Nj=1Md(ij)

    输入输出格式

    输入格式:

    输入文件包含多组测试数据。第一行,一个整数T,表示测试数据的组数。接下来的T行,每行两个整数N、M。

    输出格式:

    T行,每行一个整数,表示你所求的答案。

    输入输出样例

    输入样例#1: 复制
    2
    7 4
    5 6
    输出样例#1: 复制
    110
    121

    说明

    1<=N, M<=50000

    1<=T<=50000

    有一个定理

    $dleft(i,j ight) =sum _{x|i}sum _{y|j}left[ gcd left( x,y ight) = 1 ight]$

    然后大力推公式就好了

    后面两项暴力分块预处理

    // luogu-judger-enable-o2
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int MAXN=1e6+10;
    inline int read()
    {
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int N,M;
    int vis[MAXN],prime[MAXN],tot=0,mu[MAXN];
    long long divv[MAXN];
    void GetMu()
    {
        vis[1]=1;mu[1]=1;
        for(int i=2;i<=N;i++)
        {
            if(vis[i]==0) prime[++tot]=i,mu[i]=-1;
            for(int j=1;j<=tot&&i*prime[j]<=N;j++)
            {
                vis[i*prime[j]]=1;
                if(i%prime[j]==0){mu[i*prime[j]]=0;break;}
                else mu[i*prime[j]]=-mu[i];
            }
        }
        for(int i=1;i<=N;i++) 
            mu[i]+=mu[i-1];
        for(int i=1;i<=N;i++)
            for(int j=1,nxt;j<=i;j=nxt+1)
                nxt=i/(i/j),
                divv[i]+=(long long )(nxt-j+1)*(i/j);
    }
    main()
    {
        #ifdef WIN32
        freopen("a.in","r",stdin);
        #else
    //    freopen("SDOI2015yue.in","r",stdin);
    //    freopen("SDOI2015yue.out","w",stdout);
        #endif
        N=50000; 
        GetMu();
        int QWQ=read();
        while(QWQ--)
        {
            long long ans=0;
            N=read(),M=read();
            if(N>M) swap(N,M);
            for(int i=1,nxt;i<=N;i=nxt+1)
            {
                nxt=min(N/(N/i),M/(M/i));
                ans+=(long long )(mu[nxt]-mu[i-1])*divv[N/i]*divv[M/i];
            } 
            printf("%lld
    ",ans);
        }
        return 0;
    } 
  • 相关阅读:
    Python3 基本数据类型
    C语言使用以及其它语言经常出的错误
    Deleting array elements in JavaScript
    postgresql 导出建表语句的方法-类似describe table
    什么是分布式系统(通俗易懂的说法)
    什么是分布式系统,分布式系统例子?
    【转】Linux cp -a用法
    [转]Go基础之锁的初识
    fabricJs使用系列(一)
    chrome 的onbeforeunload事件没有触发
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/8540662.html
Copyright © 2020-2023  润新知