zoukankan      html  css  js  c++  java
  • [BZOJ]2820: YY的GCD

    Time Limit: 10 Sec  Memory Limit: 512 MB

    Description

      神犇YY虐完数论后给傻×kAc出了一题给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少对kAc这种傻×必然不会了,于是向你来请教……多组输入

    Input

      第一行一个整数T 表述数据组数接下来T行,每行两个正整数,表示N, M

    Output

      T行,每行一个整数表示第i组数据的结果

    Sample Input

      2
      10 10
      100 100

    Sample Output

      30
      2791

    HINT

      T = 10000
      N, M <= 10000000

    Solution

      枚举质数p,答案即为$sum_{p}sum_{i=1}^{left lfloor n/p ight floor}sum_{j=1}^{left lfloor m/p ight floor}left [  gcd(i,j)=1 ight ]=sum_{p}sum_{i=1}^{left lfloor n/p ight floor}sum_{j=1}^{left lfloor m/p ight floor}sum_{d|i,d|j}mu (d)$

      考虑每个d,则原式等于$sum_{p}sum_{d=1}^{leftlfloor min(n,m)/p ight floor}leftlfloor frac{n}{pd} ight floor leftlfloor frac{m}{pd} ight floor mu (d)$

      令k=pd,得到$sum_{k=1}^{min(n,m)}leftlfloor frac{n}{k} ight floor leftlfloor frac{m}{k} ight floor sum_{p|k}mu(frac{k}{p})$

      用筛法可以预处理出每个k对应的$sum_{p|k}mu(frac{k}{p})$,前缀和后利用$leftlfloor frac{n}{k} ight floor leftlfloor frac{m}{k} ight floor$只有$O(sqrt{n})$种取值,我们可以在$O(sqrt{n})$的时间内计算每次询问,总复杂度$O(n+Tsqrt{n})$。

    Code

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define ll long long
    inline int read()
    {
        int x;char c;
        while((c=getchar())<'0'||c>'9');
        for(x=c-'0';(c=getchar())>='0'&&c<='9';)x=(x<<3)+(x<<1)+c-'0';
        return x;
    }
    #define MN 10000000
    int mu[MN+5],p[MN+5],pn;
    ll f[MN+5];
    bool u[MN+5];
    int main()
    {
        int T=read(),n,m,i,j;ll ans;
        for(mu[1]=1,i=2;i<=MN;++i)
        {
            if(!u[i])p[++pn]=i,mu[i]=-1;
            for(j=1;i*p[j]<=MN&&(u[i*p[j]]=1);++j)
                if(i%p[j])mu[i*p[j]]=-mu[i];else break;
        }
        for(i=1;i<=pn;++i)for(j=1;j*p[i]<=MN;++j)f[j*p[i]]+=mu[j];
        for(i=1;i<=MN;++i)f[i]+=f[i-1];
        while(T--)
        {
            n=read();m=read();ans=0;
            for(i=1;i<=n&&i<=m;i=j+1)j=min(n/(n/i),m/(m/i)),ans+=(f[j]-f[i-1])*(n/i)*(m/i);
            printf("%lld
    ",ans);
        }
    }
  • 相关阅读:
    团队项目-典型用户及用户场景分析
    课堂小练习-找“水王”
    课堂小练习—电梯
    团队项目—用户需求调研报告
    课堂小练习
    团队项目的NABC
    梦断代码—随笔三
    梦断代码—随笔二
    结对开发5_循环二维数组最大字数组
    结对开发4_循环数组的最大值
  • 原文地址:https://www.cnblogs.com/ditoly/p/BZOJ2820.html
Copyright © 2011-2022 走看看