zoukankan      html  css  js  c++  java
  • P3455 [POI2007]ZAP-Queries

    对于这种与gcd有关的莫比乌斯反演,一般我们都是套路的去设f(d)为gcd(i,j)=d的个数,F(n)为gcd(i,j)=d和d的倍数的个数,然后用莫比乌斯反演,然后整出一个可以整数分块的东西.

    等我学完latex再发式子,详情可见luogu题解.

    题干:

    FGD正在破解一段密码,他需要回答很多类似的问题:对于给定的整数a,b和d,有多少正整数对x,y,满足x<=a,y<=b,并且gcd(x,y)=d。作为FGD的同学,FGD希望得到你的帮助。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    #include<vector>
    #include<complex>
    #include<cstring>
    using namespace std;
    #define duke(i,a,n) for(int i = a;i <= n;i++)
    #define lv(i,a,n) for(int i = a;i >= n;i--)
    #define clean(a) memset(a,0,sizeof(a))
    #define mp make_pair
    #define cp complex<db>
    #define enter puts("")
    const long long INF = 1LL << 60;
    const double eps = 1e-8;
    typedef long long ll;
    typedef double db;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x)
    {
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    const int N = 50005;
    int miu[N],sum[N],tot = 0,che[N],pri[N];
    void init()
    {
        miu[1] = 1;
        duke(i,2,N)
        {
            if(!che[i])
            {
                pri[++tot] = i;
                miu[i] = -1;
            }
            duke(j,1,tot)
            {
                if(i * pri[j] > N) break;
                che[i * pri[j]] = 1;
                if(!(i % pri[j]))
                break;
                else
                miu[pri[j] * i] = -miu[i];
            }
        }
        duke(i,1,N)
        sum[i] = sum[i - 1] + miu[i];
    }
    int T;
    int main()
    {
        read(T);
        init();
        while(T--)
        {
            ll n,m,d,ans = 0;
            read(n);read(m);read(d);
            n /= d;m /= d;
            if(n < m) swap(n,m);
            for(int i = 1;i <= m;)
            {
                int t;
                t = min(n,min(n / (n / i),m / (m / i)));
                ans += (sum[t] - sum[i - 1]) * (n / i) * (m / i);
                i = t + 1;
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    hdu 3996
    poj 3189
    poj 2391
    zoj 3165
    【Visual Studio】
    httpwebrequest Winform 上传图片
    [MVC] win7 下 配置 IIS 问题
    win7 下 升级 vs2008
    [Visual Studio 2010] NET 4.0 WinForm无法引用System.Web.dll的解决方法
    [XML] XML
  • 原文地址:https://www.cnblogs.com/DukeLv/p/10077229.html
Copyright © 2011-2022 走看看