emm不管了…BZOJ算的是总时限我才能A..
一开始用的拉格朗日插值,然后发现太慢,于是换成伯努利数..
$$ \sum_{1\le i\le n}{\text{gcd}\left( i,n \right) ^x\text{lcm}\left( i,n \right) ^y} \\ =n^y\sum_{1\le i\le n}{\text{gcd}\left( i,n \right) ^{x-y}i^y} \\ =n^y\sum_{d|n}{d^{x-y}\sum_{1\le i\le n}{i^y\left[ \text{gcd}\left( i,n \right) =d \right]}} \\ =n^y\sum_{d|n}{d^x\sum_{1\le i\le \lfloor \frac{n}{d} \rfloor}{i^y\left[ \text{gcd}\left( i,\frac{n}{d} \right) =1 \right]}} \\ =n^y\sum_{d|n}{d^x\sum_{1\le i\le \lfloor \frac{n}{d} \rfloor}{i^y\sum_{k|\text{gcd}\left( i,\frac{n}{d} \right)}{\mu \left( k \right)}}} \\ =n^y\sum_{d|n}{d^x\sum_{1\le k\le \lfloor \frac{n}{d} \rfloor}{\mu \left( k \right) \sum_{1\le i\le \frac{n}{d}}{i^y\left[ k|i \right] \left[ k|\frac{n}{d} \right]}}} \\ =n^y\sum_{d|n}{d^x\sum_{k|\frac{n}{d}}{\mu \left( k \right) \sum_{k|i,i\le \frac{n}{d}}{i^y}}} \\ =n^y\sum_{d|n}{d^x\sum_{k|\frac{n}{d}}{\mu \left( k \right) k^y\sum_{1\le i\le \frac{n}{kd}}{i^y}}} \\ \text{设}S\left( n \right) =\sum_{1\le i\le n}{i^y} \\ \text{原式}=n^y\sum_{d|n}{\left( \frac{n}{d} \right) ^x\sum_{k|d}{\mu \left( k \right) k^yS\left( \frac{d}{k} \right)}} \\ =n^y\sum_{k|n}{\mu \left( k \right) k^y\sum_{k|d,d|n}{S\left( \frac{ik}{k} \right) \left( \frac{n}{ik} \right) ^x}} \\ =n^y\sum_{k|n}{\mu \left( k \right) k^y\sum_{1\le i\le \frac{n}{k},i|\frac{n}{k}}{S\left( i \right) \left( \frac{n}{ik} \right) ^x}} \\ =n^y\sum_{k|n}{\mu \left( k \right) k^y\sum_{i|\frac{n}{k}}{S\left( i \right) \left( \frac{n}{ik} \right) ^x}} \\ =n^y\sum_{k|n}{\mu \left( \frac{n}{k} \right) \left( \frac{n}{k} \right) ^y\sum_{d|k}{S\left( d \right) \left( \frac{k}{d} \right) ^x}} \\ =n^y\sum_{d|n}{S\left( d \right) \sum_{i|\frac{n}{d}}{\mu \left( \frac{n}{id} \right) \left( \frac{n}{id} \right) ^y}}\left( i \right) ^x \\ =n^y\sum_{d|n}{S\left( d \right) \left( \frac{n}{d} \right) ^x\sum_{i|\frac{n}{d}}{\mu \left( i \right) \left( \frac{1}{i} \right) ^{x-y}}} \\ \text{此时如果}x=y,\text{则原式}=n^y\sum_{d|n}{S\left( d \right) \left( \frac{n}{d} \right) ^x\left[ n=d \right] =n^yS\left( n \right)} \\ \text{否则原式}=n^y\sum_{d|n}{S\left( d \right) \left( \frac{n}{d} \right) ^x\prod_{p\,\,| \frac{n}{d}\,\,and\,\,p\,\,is\,\,a\,\,prime}{\left( 1-\left( \frac{1}{p} \right) ^{x-y} \right)}}\left( x\ne y \right) \\ \text{设}f\left( n \right) =\prod_{p\,\,| n\,\,and\,\,p\,\,is\,\,a\,\,prime}{\left( 1-\left( \frac{1}{p} \right) ^{x-y} \right)},f\text{函数可以在枚举约数时顺便处理出来} \\ \\ \text{又因为}S\left( n \right) =\sum_{1\le i\le n}{i^y}=\frac{1}{y+1}\sum_{0\le i\le y}{\left( \begin{array}{c} y+1\\ i\\ \end{array} \right) B_in^{y+1-i}} \\ =\frac{1}{y+1}\sum_{-y\le -i\le 0}{\left( \begin{array}{c} y+1\\ i\\ \end{array} \right) B_in^{y+1-i}} \\ =\frac{1}{y+1}\sum_{0\le y-i\le y}{\left( \begin{array}{c} y+1\\ i\\ \end{array} \right) B_in^{y+1-i}} \\ =\frac{1}{y+1}\sum_{1\le y-i+1\le y+1}{\left( \begin{array}{c} y+1\\ y-i+1\\ \end{array} \right) B_{y-i+1}n^{y+1-\left( y-i+1 \right)}} \\ =\frac{1}{y+1}\sum_{1\le i\le y+1}{\left( \begin{array}{c} y+1\\ i\\ \end{array} \right) B_{y-i+1}n^i} \\ \text{故预处理出伯努利数后,可以在}O\left( n \right) \text{的时间内计算出多项式}S\left( n \right) \\ \text{由于}\sum_{0\le i\le m}{\left( \begin{array}{c} m+1\\ i\\ \end{array} \right) B_i=\left[ m=0 \right]} \\ \text{故}B_0=\text{1,对于}i>0 \\ \left( \begin{array}{c} m+1\\ m\\ \end{array} \right) B_m+\sum_{0\le i<m}{\left( \begin{array}{c} m+1\\ i\\ \end{array} \right) B_i=0} \\ B_m=-\frac{\sum_{0\le i<m}{\left( \begin{array}{c} m+1\\ i\\ \end{array} \right) B_i}}{m+1} \\ $$
#include <inttypes.h>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <random>
#include <unordered_map>
#include <utility>
#include <vector>
#define debug(x) std::cout << #x << " = " << x << std::endl;
typedef long long int int_t;
using std::cin;
using std::cout;
using std::endl;
using pair_t = std::pair<int_t, int_t>;
const int_t mod = 1e9 + 7;
const int_t LARGE = 3003;
int_t B[LARGE + 10], fact[LARGE + 10], factInv[LARGE + 10];
std::mt19937 gen;
int_t mul(int_t a, int_t b, int_t mod) { return (__int128_t)a * b % mod; }
int_t C(int_t n, int_t m) {
return fact[n] * factInv[m] % mod * factInv[n - m] % mod;
}
int_t power(int_t base, int_t index, int_t mod) {
int_t result = 1;
if (index < 0) {
index += mod - 1;
}
while (index) {
if (index & 1) result = mul(result, base, mod);
index >>= 1;
base = mul(base, base, mod);
}
return result;
}
bool isPrime(int_t n) {
if (n <= 1) return false;
if (n == 2 || n == 3) return true;
int_t s = 0, t = n - 1;
while (t % 2 == 0) {
t /= 2;
s++;
}
std::uniform_int_distribution<int_t> rand_int(2, n - 1);
for (int_t _i = 1; _i <= 3; _i++) {
int_t a = rand_int(gen);
int_t prev = power(a, t, n);
for (int_t i = 1; i <= s; i++) {
int_t curr = mul(prev, prev, n);
if (curr == 1 && prev != 1 && prev != n - 1) return false;
prev = curr;
}
if (prev != 1) return false;
}
return true;
}
int_t gcd(int_t a, int_t b) {
if (b == 0) return a;
return gcd(b, a % b);
}
int_t getFactor(int_t n, int_t c) {
const auto f = [=](int_t x) { return (mul(x, x, n) + c) % n; };
std::uniform_int_distribution<int_t> rand_int(2, n - 1);
int_t x = rand_int(gen), y = rand_int(gen);
int_t i = 0, k = 2;
int_t prod = 1, factor = 1;
while (true) {
i++;
x = f(x);
prod = mul(prod, std::abs(x - y), n);
if (i % 256 == 0) {
factor = gcd(prod, n);
if (factor > 1) return factor;
}
if (x == y) return n;
if (i == k) {
i = 0;
k *= 2;
y = x;
factor = std::max(factor, gcd(n, prod));
if (factor > 1) return factor;
prod = 1;
factor = 1;
}
}
}
template <class CT>
void pollardRho(int_t n, CT& output) {
if (isPrime(n)) {
output[n] += 1;
return;
}
int_t seed = gen();
int_t factor = n;
while (factor == n) {
factor = getFactor(factor, seed--);
if (seed == 0) seed = gen();
}
pollardRho(factor, output);
pollardRho(n / factor, output);
}
void getPoly(int_t y, int_t* output) {
int_t prod = power(y + 1, mod - 2, mod);
output[0] = 0;
for (int_t i = 1; i <= y + 1; i++)
output[i] = C(y + 1, i) * B[y - i + 1] % mod * prod % mod;
}
void DFS(int_t n, const std::unordered_map<int_t, int_t>& primeVals,
std::vector<pair_t>& counts, int_t prod, int_t funcProd,
std::vector<pair_t>& output) {
if (n >= counts.size()) {
#ifdef DEBUG
cout << "divisor " << prod << " func " << funcProd << endl;
#endif
output.push_back(pair_t(prod, funcProd));
return;
}
//²»¿¼ÂÇÕâ¸öÒòÊý
#ifdef DEBUG
cout << "setting " << counts[n].first << " time to " << 0
<< " and prev = " << 1 << "curr n = " << n << endl;
#endif
DFS(n + 1, primeVals, counts, prod, funcProd, output);
int_t prev = counts[n].first;
for (int_t i = 1; i <= counts[n].second; i++) {
#ifdef DEBUG
cout << "setting " << counts[n].first << " time to " << i
<< " and prev = " << prev << "curr n = " << n << endl;
#endif
DFS(n + 1, primeVals, counts, prod * prev,
funcProd * primeVals.at(counts[n].first) % mod, output);
prev = prev * counts[n].first;
}
#ifdef DEBUG
cout << "backing " << endl;
#endif
}
int_t process(int_t n, int_t x, int_t y) {
static int_t poly[LARGE + 10];
memset(poly, 0, sizeof(poly));
getPoly(y, poly);
const auto sub = [&](int_t x) {
//ÌØÅÐy=0
if (y == 0) return x;
int_t result = 0;
int_t pow = 1;
x %= mod;
x += 1;
for (int_t i = 1; i <= y + 1; i++) {
result = (result + poly[i] * pow % mod) % mod;
pow = pow * x % mod;
}
#ifdef DEBUG
cout << "sub " << x << " = " << result << endl;
#endif
return result;
};
#ifdef DEBUG
while (true) {
int_t x;
cin >> x;
cout << sub(x) << endl;
}
#endif
if (x == y) {
return power(n, y, mod) * sub(n) % mod;
}
std::unordered_map<int_t, int_t> output;
pollardRho<std::unordered_map<int_t, int_t>>(n, output);
#ifdef DEBUG
for (const auto& kvp : output)
cout << kvp.first << " = " << kvp.second << endl;
#endif
std::unordered_map<int_t, int_t> primeVals;
std::vector<pair_t> counts;
std::vector<pair_t> divisors;
std::unordered_map<int_t, int_t> func;
for (const auto& kvp : output) {
primeVals[kvp.first] =
(1 - power(kvp.first, (y - x + mod - 1) % (mod - 1), mod) + mod) %
mod;
counts.push_back(kvp);
}
DFS(0, primeVals, counts, 1, 1, divisors);
for (const auto& kvp : divisors) {
func[kvp.first] = kvp.second;
}
int_t result = 0;
for (const auto& kvp : divisors) {
int_t d = kvp.first;
result = (result + sub(d) * power(n, x, mod) % mod *
power(d, mod - 1 - x, mod) % mod * func[n / d] %
mod) %
mod;
#ifdef DEBUG
cout << "divisor " << d << " count "
<< sub(d) * power(n, x, mod) % mod * power(d, mod - 1 - x, mod) %
mod * func[n / d] % mod
<< endl;
#endif
}
result = result * power(n, y, mod) % mod;
return result;
}
int main() {
fact[0] = fact[1] = factInv[0] = factInv[1] = 1;
for (int_t i = 2; i <= LARGE + 2; i++) {
fact[i] = fact[i - 1] * i % mod;
factInv[i] = (mod - mod / i) * factInv[mod % i] % mod;
}
for (int_t i = 2; i <= LARGE + 2; i++)
factInv[i] = factInv[i - 1] * factInv[i] % mod;
B[0] = 1;
for (int_t i = 1; i <= LARGE + 2; i++) {
int_t sum = 0;
for (int_t j = 0; j < i; j++)
sum = (sum + C(i + 1, j) * B[j] % mod) % mod;
B[i] = (mod - sum) * power(i + 1, mod - 2, mod) % mod;
#ifdef DEBUG
if (i <= 10) cout << "B " << i << " = " << B[i] << endl;
#endif
}
gen.seed(std::random_device()());
int_t T;
cin >> T;
while (T--) {
int_t n, x, y;
cin >> n >> x >> y;
cout << process(n, x, y) << endl;
}
return 0;
}