BZOJ4659:lcm

传送门
题目所给的不合法的条件可以转化为
∃ p , p 2 ∣ g c d ( a , b ) ⇔ μ ( g c d ( a , b ) ) ≠ 0 \exists p,p^2|gcd(a,b) \Leftrightarrow \mu(gcd(a,b))\ne 0 p,p2gcd(a,b)μ(gcd(a,b))̸=0
那么
a n s = ∑ a = 1 A ∑ b = 1 B [ μ ( g c d ( i , j ) ) ≠ 0 ] a b g c d ( a , b ) ans=\sum_{a=1}^{A}\sum_{b=1}^{B}[\mu(gcd(i,j))\ne 0]\frac{ab}{gcd(a,b)} ans=a=1Ab=1B[μ(gcd(i,j))̸=0]gcd(a,b)ab
不妨假设 A ≤ B A\le B AB,枚举 g c d gcd gcd 之后经典莫比乌斯反演
S ( x ) = ∑ i = 1 x i S(x)=\sum_{i=1}^{x}i S(x)=i=1xi
得到
∑ i = 1 A S ( ⌊ A i ⌋ ) S ( ⌊ B i ⌋ ) ∑ d ∣ i [ μ ( d ) ≠ 0 ] ( i d ) 2 μ ( i d ) d \sum_{i=1}^{A}S(\lfloor\frac{A}{i}\rfloor)S(\lfloor\frac{B}{i}\rfloor)\sum_{d|i}[\mu(d)\ne 0](\frac{i}{d})^2\mu(\frac{i}{d})d i=1AS(iA)S(iB)di[μ(d)̸=0](di)2μ(di)d
后面的狄利克雷卷积是一个积性函数,直接线性筛

# include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned int uint;

const int maxn(4e6 + 5);
const int mod(1 << 30);

int test, pr[maxn], tot, n, m, cnt[maxn], pwd[maxn];
uint ans, s[maxn];
bitset <maxn> ispr;

inline uint S(uint x) {
	return (x & 1) ? (x + 1) / 2 * x : x / 2 * (x + 1);
}

int main() {
	register uint i, j;
	ispr[1] = 1, s[1] = 1;
	for (i = 2; i < maxn; ++i) {
		if (!ispr[i]) pwd[i] = pr[++tot] = i, s[i] = i - i * i, cnt[i] = 1;
		for (j = 1; j <= tot && i * pr[j] < maxn; ++j) {
			ispr[i * pr[j]] = 1;
			if (i % pr[j]) {
				s[i * pr[j]] = s[i] * s[pr[j]];
				pwd[i * pr[j]] = pr[j], cnt[i * pr[j]] = 1;
			}
			else {
				cnt[i * pr[j]] = cnt[i] + 1, pwd[i * pr[j]] = pwd[i] * pr[j];
				if (cnt[i] == 1) s[i * pr[j]] = -(uint)pr[j] * pr[j] * pr[j] * s[i / pwd[i]];
				else s[i * pr[j]] = 0;
				break;
			}
		}
	}
	for (i = 2; i < maxn; ++i) s[i] += s[i - 1];
	scanf("%d", &test);
	while (test) {
		scanf("%d%d", &n, &m), test--;
		if (n > m) swap(n, m);
		for (ans = 0, i = 1; i <= n; i = j + 1) {
			j = min(n / (n / i), m / (m / i));
			ans += (s[j] - s[i - 1]) * S(n / i) * S(m / i);
		}
		printf("%u\n", ans % mod);
	}
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值