• 洛谷 P2522 [HAOI2011]Problem b


    题目链接

    先利用差分

    思想,求(f(b,d,k) - f(a - 1,d,k) - f(b,c-1,k)+f(a-1,c-1,k))

    [egin{aligned} f(n,m,k) &=sum_{i=1}^{n} sum_{j=1}^{m} [gcd(i,j) = k]\ &= sum_{i=1}^{frac nk} sum_{j=1}^{frac mk} [gcd(i,j) = 1]\ end{aligned}\ ]

    然后莫比乌斯反演

    [sum_{i=1}^{n} sum_{j=1}^{m} [gcd(i,j) = 1]\ sum_{i=1}^{n} sum_{j=1}^{m} sum_{p|i,p|j}mu(p)\ sum_{p=1}^{n}mu(p)sum_{i=1}^{frac np}sum_{j=1}^{frac mp}1\ sum_{p=1}^{n}mu(p)(frac np)(frac mp)\ ]

    最后数论分块。

    code

    #include<bits/stdc++.h>
    using namespace std;
    int p[50050],prime[50050],cnt,mu[50050];
    void init(int N){
        p[0] = p[1] = 1; mu[1] = 1;
        for(int i = 2; i <= N; ++ i){
            if(!p[i]) { prime[++ cnt] = i; mu[i] = -1; }
            for(int j = 1; 1ll * prime[j] * i <= N; ++ j){
                p[prime[j] * i] = 1;
                if(i % prime[j] == 0) break;
                mu[i * prime[j]] = -mu[i];
            }
        }
        for(int i = 1; i <= N; ++ i) mu[i] += mu[i - 1];
    }
    int f(int n, int m, int k){
        if(n > m) swap(n,m);
        n /= k; m /= k;
        if(n == 0 || m == 0) return 0;
        int ret = 0;
        for(int l = 1, r; l <= n; l = r + 1){
            r = min(min(n/(n/l), m/(m/l)), n);
            ret = ret + 1ll * (mu[r] - mu[l - 1]) * (n/l) * (m/l);
        }
        return ret;
    }
    int main(){
        init(50000);
        int T; scanf("%d",&T);
        while(T --){
            int a,b,c,d,k;
            scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
            printf("%d
    ",f(b,d,k) - f(a - 1,d,k) - f(b,c - 1,k) + f(a - 1,c - 1,k));
        }
    	return 0;
    }
    
  • 相关阅读:
    列表的排序和统计。
    pyoo6 列表 004
    py005 列表 03
    py004列表02
    py 003 列表01
    py。002 字符串(str)
    py_001 运算符
    【python--字典】 字典的嵌套
    【python--字典】 字典的增删改查
    【python--字典】 字典的有效性
  • 原文地址:https://www.cnblogs.com/zzhzzh123/p/13498544.html
Copyright © 2020-2023  润新知