zoukankan      html  css  js  c++  java
  • BZOJ2301: [HAOI2011]Problem b(莫比乌斯反演)

    Description

    对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数。

    Input

    第一行一个整数n,接下来n行每行五个整数,分别表示a、b、c、d、k

    Output

    共n行,每行一个整数表示满足要求的数对(x,y)的个数 

    Sample Input

    2
    2 5 1 5 1
    1 5 1 5 2

    Sample Output

    14
    3

    解题思路:

    和1101一样,最后二维容斥一下就好了。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    typedef long long lnt;
    const int N=50010;
    int prime[N];
    int miu[N];
    lnt s[N];
    bool vis[N];
    int cnt;
    int T;
    void gtp(void)
    {
        miu[1]=1;
        for(int i=2;i<N;i++)
        {
            if(!vis[i])
            {
                prime[++cnt]=i;
                miu[i]=-1;
            }
            for(int j=1;j<=cnt&&prime[j]*i<N;j++)
            {
                vis[prime[j]*i]=true;
                if(i%prime[j]==0)
                {
                    miu[i*prime[j]]=0;
                    break;
                }
                miu[prime[j]*i]=-miu[i];
            }
        }
        for(int i=1;i<N;i++)
            s[i]=s[i-1]+miu[i];
        return ;
    }
    lnt query(lnt a,lnt b,lnt d)
    {
        a/=d;
        b/=d;
        lnt c=std::min(a,b);
        lnt ans=0;
        for(int k=1,u;k<=c;k=u+1)
        {
            u=std::min(a/(a/k),b/(b/k));
            ans+=(s[u]-s[k-1])*(a/k)*(b/k);
        }
        return ans;
    }
    int main()
    {
        gtp();
        scanf("%d",&T);
        while(T--)
        {
            lnt a,b,c,d,k;
            scanf("%lld%lld%lld%lld%lld",&a,&b,&c,&d,&k);
            a--,c--;
            lnt ans=query(b,d,k)+query(a,c,k)-query(a,d,k)-query(b,c,k);
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    su 命令切换用户带来的问题
    系统无法启动
    Linux单用户模式
    反射
    propety/静态方法
    内置方法,序列化模块
    第1月5周3天
    第1月4周5天
    第1月4周4日
    第1月4周3日
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10161311.html
Copyright © 2011-2022 走看看