• BZOJ 4407: 于神之怒加强版 [莫比乌斯反演 线性筛]


    题意:提前给出(k),求(sumlimits_{i=1}^n sumlimits_{j=1}^m gcd(i,j)^k)


    套路推♂倒

    [sum_{D=1}^n sum_{d|D} d^kmu(frac{D}{d}) frac{n}{D} frac{m}{D} ]

    是一个(g = idk * mu)啊,单位幂函数和莫比乌斯函数的卷积!

    (g(1) = 1)
    (g(p) = -1 + p^k)
    因为带着(mu),只有sf才有贡献
    所以(p mid i)只能把(p)放到(d^k)里了,就是(g(i)cdot p)
    或者考虑(g(p^k))只有1和p有贡献也可以,直接得到计算公式再递推

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    using namespace std;
    const int N=5e6+5, INF=1e9, P=1e9+7;
    #define pii pair<int, int>
    #define MP make_pair 
    #define fir first
    #define sec second
    typedef long long ll;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
     
    int n, m, k;
    int notp[N], p[N], mu[N];
    ll pk[N], g[N];
    inline ll Pow(ll a, int b) {
        ll ans = 1;
        for(; b; b>>=1, a=a*a%P)
            if(b&1) ans = ans*a%P;
        return ans;
    }
    inline ll powk(int a) {return pk[a] ? pk[a] : pk[a]=Pow(a, k);}
    void sieve(int n) {
        mu[1] = 1; g[1] = 1;
        for(int i=2; i<=n; i++) {
            if(!notp[i]) p[++p[0]] = i, mu[i] = -1, g[i] = -1 + powk(i);
            for(int j=1; j<=p[0] && i*p[j]<=n; j++) {
                int t = i*p[j];
                notp[t] = 1;
                if(i%p[j] == 0) {
                    g[t] = g[i]*powk(p[j])%P;
                    mu[t] = 0;
                    break;
                }
                g[t] = g[i]*g[p[j]]%P;
                mu[t] = -mu[i];
            }
        }
        for(int i=1; i<=n; i++) g[i] = (g[i] + g[i-1])%P;
    }
    ll cal(int n, int m) {
        ll ans=0; int r;
        for(int i=1; i<=n; i=r+1) {
            r = min(n/(n/i), m/(m/i));
            ans = (ans+ (g[r] - g[i-1]) * (n/i)%P * (m/i)%P )%P;
        }
        return (ans + P) %P;
    }
    int main() {
        //freopen("in","r",stdin);
        int T=read(); k=read(); 
        sieve(N-1);
        while(T--) {
            n=read(); m=read();
            if(n>m) swap(n, m);
            printf("%lld
    ", cal(n, m));
        }
    }
    
  • 相关阅读:
    docker 安装使用jenkins
    docker 安装禅道
    在linux定时执行docker容器的命令不成功
    docker 安装nginx+php
    php发起http请求
    安装docker
    REST(Respresentaional State Transfer 表现层状态转化)
    git 分支操作
    git常用命令
    php多进程编程
  • 原文地址:https://www.cnblogs.com/candy99/p/6611680.html
Copyright © 2020-2023  润新知