[BZOJ 3561] DZY Loves Math VI

本文解析了一道BZOJ平台上的数学题,通过复杂的数学公式推导,给出了求解特定数学表达式的算法思路,涉及枚举、前缀和等技巧,最终实现O(Nln(N))的时间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

BZOJ传送门

Description

给定正整数 n , m n,m n,m。求

img

Input

一行两个整数 n , m n,m n,m

Output

一个整数,为答案模 1000000007 1000000007 1000000007后的值。

Sample Input

5 4

Sample Output

424

HINT

数据规模:

1 ≤ n , m ≤ 500000 1\le n,m\le 500000 1n,m500000,共有3组数据。

解题分析

∑ i = 1 n ∑ j = 1 m l c m ( i , j ) g c d ( i , j ) = ∑ d = 1 n ∑ i = 1 n ∑ j = 1 m ( i j d ) d [ g c d ( i , j ) = d ] = ∑ d = 1 n ∑ i = 1 ⌊ n d ⌋ ∑ j = 1 ⌊ m d ⌋ ( d i j ) d [ g c d ( i , j ) = 1 ] = ∑ d = 1 n d d ∑ p = 1 ⌊ n d ⌋ μ ( p ) ∑ i = 1 ⌊ n d p ⌋ ∑ j = 1 ⌊ m d p ⌋ ( i j p 2 ) d = ∑ d = 1 n d d ∑ p = 1 ⌊ n d ⌋ μ ( p ) p 2 d ∑ i = 1 ⌊ n d p ⌋ ∑ j = 1 ⌊ m d p ⌋ ( i j ) d \sum_{i=1}^{n}\sum_{j=1}^{m}lcm(i,j)^{gcd(i,j)} \\ =\sum_{d=1}^{n}\sum_{i=1}^{n}\sum_{j=1}^{m}(\frac{ij}{d})^d[gcd(i,j)=d] \\ =\sum_{d=1}^{n}\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor}(dij)^d[gcd(i,j)=1] \\ =\sum_{d=1}^{n}d^d\sum_{p=1}^{\lfloor\frac{n}{d}\rfloor}\mu(p)\sum_{i=1}^{\lfloor\frac{n}{dp}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{dp}\rfloor}(ijp^2)^d \\ =\sum_{d=1}^{n}d^d\sum_{p=1}^{\lfloor\frac{n}{d}\rfloor}\mu(p)p^{2d}\sum_{i=1}^{\lfloor\frac{n}{dp}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{dp}\rfloor}(ij)^d i=1nj=1mlcm(i,j)gcd(i,j)=d=1ni=1nj=1m(dij)d[gcd(i,j)=d]=d=1ni=1dnj=1dm(dij)d[gcd(i,j)=1]=d=1nddp=1dnμ(p)i=1dpnj=1dpm(ijp2)d=d=1nddp=1dnμ(p)p2di=1dpnj=1dpm(ij)d

看起来不是很能再化简了?

其实我们可以发现, 枚举 d d d再枚举 p p p的复杂度是 O ( N l n ( N ) ) O(Nln(N)) O(Nln(N)), 完全可以过这道题, 那么我们只需要再维护一个 i d i^d id以及它的前缀和就好了。

总复杂度 O ( N l n ( N ) ) O(Nln(N)) O(Nln(N))

代码如下:

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstdlib>
#include <cctype>
#include <cstring>
#define R register
#define IN inline
#define W while
#define gc getchar()
#define MX 500050
#define MOD 1000000007ll
#define ll long long
int pcnt;
int miu[MX], pri[MX];
ll mul[MX], sum[MX];
bool npr[MX];
void get()
{
	miu[1] = 1; R int i, j, tar;
	for (i = 2; i <= 5e5; ++i)
	{
		if (!npr[i]) npr[i] = true, pri[++pcnt] = i, miu[i] = -1;
		for (j = 1; j <= pcnt; ++j)
		{
			tar = i * pri[j];
			if (tar > 5e5) break;
			npr[tar] = true;
			if (!(i % pri[j])) {miu[tar] = 0; break;}
			miu[tar] = -miu[i];
		}
	}
}
IN ll fpow(ll base, R int tim)
{
	ll ret = 1;
	W (tim)
	{
		if (tim & 1) ret = ret * base % MOD;
		base = base * base % MOD, tim >>= 1;
	}
	return ret;
}
int main(void)
{
	int n, m, bdn, bdm; ll ans = 0, mt, tot;
	scanf("%d%d", &n, &m); get();
	if (n > m) std::swap(n, m);
	for (R int i = 1; i <= m; ++i) mul[i] = 1;
	for (R int i = 1; i <= n; ++i)
	{
		bdn = n / i, bdm = m / i, tot = 0;
		for (R int j = 1; j <= bdm; ++j)
		mul[j] = mul[j] * j % MOD, sum[j] = (sum[j - 1] + mul[j]) % MOD;
		for (R int j = 1; j <= bdn; ++j)
		{
			mt = miu[j] % MOD * mul[j] % MOD * mul[j] % MOD;
			(tot += mt * sum[bdn / j] % MOD * sum[bdm / j] % MOD) %= MOD;
		}
		ans = (ans + fpow(i, i) * tot % MOD) % MOD;
	}
	printf("%lld", (ans + MOD) % MOD);
}

内容概要:本文探讨了在MATLAB/SimuLink环境中进行三相STATCOM(静态同步补偿器)无功补偿的技术方法及其仿真过程。首先介绍了STATCOM作为无功功率补偿装置的工作原理,即通过调节交流电压的幅值和相位来实现对无功功率的有效管理。接着详细描述了在MATLAB/SimuLink平台下构建三相STATCOM仿真模型的具体步骤,包括创建新模型、添加电源和负载、搭建主电路、加入控制模块以及完成整个电路的连接。然后阐述了如何通过对STATCOM输出电压和电流的精确调控达到无功补偿的目的,并展示了具体的仿真结果分析方法,如读取仿真数据、提取关键参数、绘制无功功率变化曲线等。最后指出,这种技术可以显著提升电力系统的稳定性与电能质量,展望了STATCOM在未来的发展潜力。 适合人群:电气工程专业学生、从事电力系统相关工作的技术人员、希望深入了解无功补偿技术的研究人员。 使用场景及目标:适用于想要掌握MATLAB/SimuLink软件操作技能的人群,特别是那些专注于电力电子领域的从业者;旨在帮助他们学会建立复杂的电力系统仿真模型,以便更好地理解STATCOM的工作机制,进而优化实际项目中的无功补偿方案。 其他说明:文中提供的实例代码可以帮助读者直观地了解如何从零开始构建一个完整的三相STATCOM仿真环境,并通过图形化的方式展示无功补偿的效果,便于进一步的学习与研究。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值