• Luogu 4449 于神之怒加强版


    挺套路的题,然而一开始还是想错了……

    $sum_{i = 1}^{n}sum_{j = 1}^{m}gcd(i, j) ^ {k} = sum_{T = 1}^{min(n, m)}left lfloor frac{n}{T} ight floor left lfloor frac{m}{T} ight floorsum_{d | T}mu (frac{T}{d}) * d^{k}$

    我们设$h(i) =sum_{d | T}mu (frac{T}{d}) * d^{k} $, 那么原式化为$ sum_{T = 1}^{min(n, m)}left lfloor frac{n}{T} ight floor left lfloor frac{m}{T} ight floor h(i)$

    我们做出$h(i)$的前缀和之后就可以整除分块了。

    发现$h(i)$是一个积性函数,可以线性筛,具体筛法如下:

    1、$h(1) = 1$

    2、$h(p) = p^{k} - 1$($p$是一个质数)

    3、考虑线性筛中的过程,$i * pri_{j}$被它的最小因子也就是$pri_{j}$筛掉,那么当$i$不是$pri_{j}$的倍数的时候,也就是说$h(i * pri_{j}) = h(i) * h(pri_{j})$。

      而当$pri_{j} | i$的时候,考虑分两步:($ i = prod_{j = 1}^{m}p_{j}^{c_{j}}$)

      记$low_{i} =$ $i$的最小质因子被$i$包含的最大幂次积(即$p_{1} ^ {c_{1}}$)

      a、我们假设$low_{i}$不等于$i$,这句话等价于$i$不是一个质数的倍数,所以$frac{i}{low_{i}}$ 与 $pri_{j} * low_{i}$互质,那么直接乘上就好了。

      b、当$low_{i}$等于$i$的时候,我们考虑一下$h(i)$函数的定义,展开式子之后发现$h(i) = pri_{j} ^ {mk} - pri_{j} ^ {(m - 1)k}$,而$h(i  * pri_{j}) = pri_{j} ^ {(m + 1)k} - pri_{j} ^ {mk}$,那么就相当于$h(i * pri_{j}) = h(i) * pri_{j}^{k}$。

    时间复杂度$O(maxNlogmaxN + Tsqrt{n})$。

    大时限题还感觉跑得挺快的。

    Code:

    #include <cstdio>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    
    const int N = 5e6 + 5;
    const ll P = 1e9 + 7;
    
    int testCase, pCnt = 0, pri[N];
    ll k, h[N], low[N], sum[N];
    bool np[N];
    
    template <typename T>
    inline void read(T &X) {
        X = 0;
        char ch = 0;
        T op = 1;
        for(; ch > '9' || ch < '0'; ch = getchar())
            if(ch == '-') op = -1;
        for(; ch >= '0' && ch <= '9'; ch = getchar())
            X = (X << 3) + (X << 1) + ch - 48;
        X *= op;
    }
    
    inline ll pow(ll a, ll b) {
        ll res = 1LL;
        for(; b > 0; b >>= 1) {
            if(b & 1) res = res * a % P;
            a = a * a % P;
        }
        return res;
    }
    
    inline void sieve() {
        h[1] = 1LL;
        for(int i = 2; i < N; i++) {
            if(!np[i]) {
                pri[++pCnt] = i;
                low[i] = (ll)i;
                h[i] =
                 (pow(i, k) - 1LL + P) % P;
            }
            for(int j = 1; j <= pCnt && pri[j] * i < N; j++) {
                np[i * pri[j]] = 1;
                if(i % pri[j] == 0) {
                    low[i * pri[j]] = low[i] * pri[j];
                    if(low[i] == i) h[i * pri[j]] = h[i] * pow(pri[j], k) % P;
                    else h[i * pri[j]] = h[i / low[i]] * h[low[i] * pri[j]] % P;
                    break;
                }
                low[i * pri[j]] = pri[j];
                h[i * pri[j]] = h[i] * h[pri[j]] % P;
            }
        }
        
        
    /*    for(int i = 1; i < 20; i++)
            printf("%lld ", phi[i]);
        printf("
    ");   
        for(int i = 1; i < 30; i++)
            printf("%lld ", h[i]);
        printf("
    ");   */
        
    /*    for(int i = 1; i <= 20; i++)
            printf("%lld ", h[i] % P);   */
        
        for(int i = 1; i < N; i++) 
            sum[i] = (sum[i - 1] + h[i] % P + P) % P;
    }
    
    inline ll min(ll x, ll y) {
        return x > y ? y : x;
    }
    
    int main() {
        read(testCase), read(k);
        sieve();
        for(ll n, m; testCase--; ) {
            read(n), read(m);
            ll ans = 0LL, rep = min(n, m);
            for(ll l = 1, r; l <= rep; l = r + 1) {
                r = min((n / (n / l)), (m / (m / l)));
                ans = (ans + (sum[r] - sum[l - 1] + P) % P * (n / l) % P * (m / l) % P) % P;
            }
            printf("%lld
    ", ans);
        } 
        return 0;
    }
    View Code
  • 相关阅读:
    牛客代码测试栈深度
    "Coding Interview Guide" -- 在行列都排好序的矩阵中找数
    "Coding Interview Guide" -- 括号字符串的有效性和最长有效长度
    "Coding Interview Guide" -- 将正方形矩阵顺时针转动90°
    "Coding Interview Guide" -- 按照左右半区的方式重新组合单链表
    "Coding Interview Guide" -- 先序、中序和后序数组两两结合重构二叉树
    "Coding Interview Guide" -- 只用位运算不用算术运算实现整数的加减乘除运算
    "Coding Interview Guide" -- 从N个数中等概率打印M个数
    "Coding Interview Guide" -- 判断字符数组中是否所有的字符都只出现过一次
    "Coding Interview Guide" -- 字符串的统计字符串
  • 原文地址:https://www.cnblogs.com/CzxingcHen/p/9523250.html
Copyright © 2020-2023  润新知