于神之怒加强版

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#define M 5000100
#define ll long long
const int mod = 1000000007;
using namespace std;

int read() {
    int nm = 0, f = 1;
    char c = getchar();
    for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
    for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';
    return nm * f;
}
bool vis[M];
ll sum[M], s[M], pri[M], tp, k;

ll poww(ll a, ll b) {
    ll ans = 1, tmp = a;
    for(; b; b >>= 1, tmp = tmp * tmp % mod) if(b & 1) ans = ans *tmp % mod;
    return ans;
}

void shai() {
    vis[1] = sum[1] = 1;
    for(int i = 2; i <= M - 100; i++) {
        if(!vis[i]) pri[++tp] = i, s[tp] = poww(i, k), sum[i] = s[tp] - 1;
        for(int j = 1; j <= tp&& 1ll * i * pri[j] <= M -100; j++) {
            vis[i * pri[j]] = true;
            if(i % pri[j] == 0) {
                sum[i * pri[j]] = sum[i] * s[j] % mod;
                break;
            } else sum[i * pri[j]] = sum[i] * sum[pri[j]] % mod;
        }
    }
    for(int i = 2; i <= M - 100; i++) sum[i] += sum[i - 1];
}

int main() {
    int t = read();
    k = read();
    shai();
    while(t--) {
        int n = read(), m = read();
        if(n > m) swap(n, m);
        int i = 1, j;
        ll ans = 0;
        while(i <= n) {
            j = min(n / (n / i), m / (m / i));
            ans += 1ll *(n / i) * (m / i) % mod * (sum[j] - sum[i - 1]) % mod;
            ans %= mod;
            i = j + 1;
        }
        cout << ans << "\n";
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/luoyibujue/p/9301939.html
今日推荐