@hdu - 6607@ Easy Math Problem


@description@

求:

\[\sum_{i=1}^{n}\sum_{j=1}^{n}gcd^k(i, j)\times lcm(i, j)\times [gcd(i, j) \in prime] \mod 10^9 + 7 \]

原题传送门。

@solution@

\[\begin{aligned} ans &= \sum_{i=1}^{n}\sum_{j=1}^{n}gcd^k(i, j)\times lcm(i, j)\times [gcd(i, j) \in prime] \\ &= \sum_{d=1}^{n}[d \in prime]\times d^{k+1}\sum_{i=1}^{\lfloor \frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor \frac{n}{d}\rfloor}[gcd(i, j) = 1]\times i \times j \end{aligned} \]

后面那个是经典问题了。虽然明显可以莫比乌斯反演,不过注意到 i, j 取值范围相同,可以用欧拉函数。

基于结论 \(gcd(i, n) = gcd(n - i, n)\),与 n 互质的数总是成对存在,所以有:

\[\sum_{i=1}^{n}\sum_{j=1}^{n}[gcd(i, j) = 1]\times i \times j = \sum_{i=1}^{n}\phi(i)\times i^2 \]

\(S(n) = \sum_{i=1}^{n}\phi(i)\times i^2\),可以用杜教筛求 \(S\)(能不用 min-25 筛就不用)。则:

\[ans = \sum_{d=1}^{n}[d \in prime]\times d^{k+1}\times S(\lfloor \frac{n}{d}\rfloor) \]

如果对 \(S(\lfloor \frac{n}{d}\rfloor)\) 分块,我们需要求质数的 k + 1 次幂的前缀和。其实就是 min-25 筛的前半部分。

@accepted code@

#include <cstdio>
#include <algorithm>
using namespace std;

typedef long long ll;

const int MOD = int(1E9) + 7;
const int MAXN = 4650000;

inline int add(int x, int y) {return (x + y >= MOD ? x + y - MOD : x + y);}
inline int sub(int x, int y) {return (x - y < 0 ? x - y + MOD : x - y);}
inline int mul(int x, int y) {return 1LL * x * y % MOD;}

int pow_mod(int b, int p) {
	int ret = 1;
	for(int i=p;i;i>>=1,b=mul(b,b))
		if( i & 1 ) ret = mul(ret, b);
	return ret;
}

bool nprm[MAXN + 5];
int prm[MAXN + 5], phi[MAXN + 5], pcnt;
void sieve() {
	phi[1] = 1;
	for(int i=2;i<=MAXN;i++) {
		if( !nprm[i] ) prm[++pcnt] = i, phi[i] = i - 1;
		for(int j=1;i*prm[j]<=MAXN;j++) {
			nprm[i*prm[j]] = true;
			if( i % prm[j] == 0 ) {
				phi[i*prm[j]] = phi[i]*prm[j];
				break;
			}
			else phi[i*prm[j]] = phi[i]*phi[prm[j]];
		}
	}
}
int c[105][105], f[105][105];
void get_coef() {
	for(int i=0;i<=102;i++) {
		c[i][0] = 1;
		for(int j=1;j<=i;j++)
			c[i][j] = add(c[i-1][j], c[i-1][j-1]);
	}
	for(int i=0;i<=101;i++) {
		for(int j=0;j<=i+1;j++)
			f[i][j] = c[i+1][j];
		for(int j=0;j<i;j++) {
			for(int k=0;k<=j+1;k++)
				f[i][k] = sub(f[i][k], mul(c[i+1][j], f[j][k]));
		}
		int iv = pow_mod(i + 1, MOD - 2);
		for(int j=0;j<=i+1;j++)
			f[i][j] = mul(f[i][j], iv);
	}
}
int get_sum(int n, int k) {
	int ret = 0;
	for(int i=k+1;i>=0;i--)
		ret = add(mul(ret, n), f[k][i]);
	return ret;
}
int sum[MAXN + 5];
void init() {
	sieve(), get_coef();
	for(int i=1;i<=MAXN;i++)
		sum[i] = add(sum[i-1], mul(mul(i, i), phi[i]));
}
ll n; int k;
int id1[MAXN + 5], id2[MAXN + 5], cnt;
int id(ll m) {return (m <= MAXN ? id1[m] : id2[n/m]);}
ll a[MAXN + 5]; int s[MAXN + 5];
void get_id() {
	cnt = 0;
	for(ll i=1;i<=n;i=(n/(n/i))+1) {
		ll p = n / i;
		if( p <= MAXN ) id1[p] = (++cnt);
		else id2[n/p] = (++cnt);
		a[cnt] = p, s[cnt] = -1;
	}
}
int phisum(ll m) {
	if( m <= MAXN ) return sum[m];
	int &ans = s[id(m)];
	if( ans != -1 ) return ans;
	ans = get_sum(m % MOD, 3);
	for(ll i=2;i<=m;i++) {
		ll p = m / i, j = m / p;
		ans = sub(ans, mul(sub(get_sum(j % MOD, 2), get_sum((i-1) % MOD, 2)), phisum(p)));
		i = j;
	}
	return ans;
}
int dp[MAXN + 5];
void get_dp() {
	for(int i=1;i<=cnt;i++) dp[i] = sub(get_sum(a[i] % MOD, k + 1), 1);
	int tmp = 0;
	for(int i=1;i<=pcnt;i++) {
		ll sq = 1LL*prm[i]*prm[i]; int del = pow_mod(prm[i], k + 1);
		if( sq > n ) break;
		for(int j=1;j<=cnt;j++) {
			if( sq > a[j] ) break;
			dp[j] = sub(dp[j], mul(del, sub(dp[id(a[j] / prm[i])], tmp)));
		}
		tmp = add(tmp, del);
	}
}
void solve() {
	scanf("%lld%d", &n, &k), get_id(), get_dp();
	
	int ans = 0;
	for(ll i=1;i<=n;i++) {
		ll p = n / i, j = n / p;
		ans = add(ans, mul(sub(phisum(j), phisum(i - 1)), dp[id(p)]));
		i = j;
	}
	printf("%d\n", ans);
}
int main() {
	init();
	int T; scanf("%d", &T);
	while( T-- ) solve();
}

@details@

整除分块时所有数都必须取 long long,但是取模要转成 int。注意一下不要出锅。


update in 2020/09/04:

如果你真的头铁,想要用莫比乌斯反演得到 \(\sum [\gcd(i, j)=1]ij = \sum\phi(i)\times i^2\)

\[\begin{aligned} \sum [\gcd(i, j)=1]ij &= \sum(\mu(d)\times d^2)(\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor} i)^2 \\ &= \sum_{d\times k\leq n} (\mu(d)\times d^2)k^3 \\ &= \sum_{d\times k = i}^{i\leq n} i^2 \mu(d) k \\ &= \sum i^2 \phi(i) \end{aligned} \]

数学本质是一样的,只是有一个比较不容易看出来的 trick:\((\sum_{i=1}^n i)^2=\sum_{i=1}^{n} i^3\)

posted @ 2020-03-15 21:48  Tiw_Air_OAO  阅读(170)  评论(0编辑  收藏  举报