zoukankan      html  css  js  c++  java
  • bzoj_2301_HAOI2011_Problem b 莫比乌斯反演

    首先,求x在[a,b]和y在[c,d]两区间gcd(x,y)==K的(x,y)个数,可以转化成求四次,然后容斥求

    现在问题变成求[1,m]和[1,n]的(x,y)==K的个数,其实就是求[1,m/K]和[1,n/K]的(x,y)==1的个数

    设F(i)=i|gcd(x,y)的(x,y)个数  f(i)=gcd(x,y)==i的个数

    那么满足

    $$ F(n)=sum_{d|n}f(d)$$

    再进行一波反演

    $$ f(i)=sum_{i|d}mu(frac{d}{i})lfloorfrac{n}{d} floorlfloorfrac{m}{d} floor$$

    $$ f(i)=sum_{d=1}^{min(n,m)}lfloorfrac{n}{d} floorlfloorfrac{m}{d} floorsum_{i|d}mu(frac{d}{i})$$

    然后就可以预处理出$mu(d)$的前缀和,求解啦

     

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <cmath>
    #include <algorithm>
    #define ll long long
    #define mem(a,b) memset(a,b,sizeof(a))
    using namespace std;
    const int N=100006;
    
    int prime[N],cnt,mu[N];
    bool he[N];
    
    void chu()
    {
        mu[1]=1;
        for(int i=2;i<N;++i)
        {
            if(!he[i])
            {
                prime[++cnt]=i;
                mu[i]=-1;
            }
            for(int j=1;j<=cnt&&prime[j]*i<N;++j)
            {
                he[i*prime[j]]=1;
                if(i%prime[j]==0)
                {
                    mu[i*prime[j]]=0;
                    break;
                }
                mu[i*prime[j]]=-mu[i];
            }
        }
    
        for(int i=1;i<N;++i)
            mu[i]+=mu[i-1];
    }
    
    int Q;
    int K;
    
    int get(int n,int m)
    {
        n/=K;m/=K;
        if(n>m)
            swap(n,m);
        int nx,ans=0;
        for(int i=1;i<=n;)
        {
            nx=min( n/(n/i),m/(m/i) );
            //printf("nx=%d
    ",nx);
            ans+=(mu[nx]-mu[i-1])*(m/i)*(n/i);
            i=nx+1;
        }
        //printf("n=%d m=%d ans=%d
    ",n,m,ans);
        return ans;
    }
    
    int main(){
    
        freopen("in.in","r",stdin);
    
        chu();
    
        scanf("%d",&Q);
        int l0,r0,l1,r1;
        for(int i=1;i<=Q;++i)
        {
            //printf("i=%d
    ",i);
            scanf("%d%d%d%d%d",&l0,&r0,&l1,&r1,&K);
            printf("%d
    ",get(r0,r1)-get(l0-1,r1)-get(l1-1,r0)+get(l0-1,l1-1));
        }
    
    }
    bzoj 2301

     

  • 相关阅读:
    Visual Studio 2012 中的ASP.NET Web API
    CentOS配置RPMForge软件源
    CentOS设置Mono环境变量
    使用 MEF 轻松实现云部署
    WiX 3.6——强大的.NET部署工具
    Redis应用场景
    How does it work in Mono's C# compiler?
    .NET程序员应该关注开源社区
    ASP.NET Web API和依赖注入
    [招聘帖]IT应用开发工程师
  • 原文地址:https://www.cnblogs.com/A-LEAF/p/7634264.html
Copyright © 2011-2022 走看看