P5572 [CmdOI2019]简单的数论题

P5572 [CmdOI2019]简单的数论题

求:

i=1nj=1mφ(lcm(i,j)gcd(i,j))mod23333\sum_{i=1}^{n}\sum_{j=1}^{m}\varphi(\frac{\operatorname{lcm}(i,j)}{\gcd(i,j)})\bmod 23333

TT 组数据,满足 T3×104,mn5×104T \leq 3 \times 10^4,m \leq n \leq 5 \times 10^4

下面默认 nmn \leq m

先化简原式,有:

i=1nj=1mφ(lcm(i,j)gcd(i,j))=i=1nj=1mφ(i×jgcd(i,j)2)=d=1ni=1nj=1mφ(i×jd2)[gcd(i,j)=d]=d=1ni=1ndj=1mdφ(i×j)[gcd(i,j)=1]=d=1ni=1ndj=1mdφ(i)φ(j)[gcd(i,j)=1]=d=1ni=1ndj=1mdφ(i)φ(j)pgcd(i,j)μ(p)=d=1np=1ndμ(p)i=1ndj=1mdφ(i)φ(j)[pi][pj]=d=1np=1ndμ(p)i=1npdφ(ip)j=1mpdφ(jp)=T=1npTμ(p)i=1nTφ(ip)j=1mTφ(jp)\begin{aligned} \sum_{i=1}^{n}\sum_{j=1}^{m}\varphi(\frac{\operatorname{lcm}(i,j)}{\gcd(i,j)})&=\sum_{i=1}^{n}\sum_{j=1}^{m}\varphi(\frac{i \times j}{\gcd(i,j)^2})\\ &=\sum_{d=1}^{n}\sum_{i=1}^{n}\sum_{j=1}^{m}\varphi(\frac{i \times j}{d^2})[\gcd(i,j)=d]\\ &=\sum_{d=1}^{n}\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor}\varphi(i\times j)[\gcd(i,j)=1]\\ &=\sum_{d=1}^{n}\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor}\varphi(i)\varphi(j)[\gcd(i,j)=1]\\ &=\sum_{d=1}^{n}\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor}\varphi(i)\varphi(j)\sum_{p|\gcd(i,j)}\mu(p)\\ &=\sum_{d=1}^{n}\sum_{p=1}^{\lfloor\frac{n}{d}\rfloor}\mu(p) \sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor}\varphi(i)\varphi(j)[p|i][p|j]\\ &=\sum_{d=1}^{n}\sum_{p=1}^{\lfloor\frac{n}{d}\rfloor}\mu(p) \sum_{i=1}^{\lfloor\frac{n}{pd}\rfloor}\varphi(ip)\sum_{j=1}^{\lfloor\frac{m}{pd}\rfloor}\varphi(jp)\\ &=\sum_{T=1}^{n}\sum_{p|T}\mu(p)\sum_{i=1}^{\lfloor\frac{n}{T}\rfloor}\varphi(ip)\sum_{j=1}^{\lfloor\frac{m}{T}\rfloor}\varphi(jp) \end{aligned}

设:

G(x,y)=i=1xφ(iy)G(x,y)=\sum_{i=1}^{x}\varphi(iy)

暴力预处理即可。

那么原式等于:

T=1npTμ(p)G(nT,p)G(mT,p)\sum_{T=1}^{n}\sum_{p|T}\mu(p)G(\lfloor\frac{n}{T}\rfloor,p)G(\lfloor\frac{m}{T}\rfloor,p)

再设:

H(x,y,z)=i=1zpiμ(p)G(x,p)g(y,p)H(x,y,z)=\sum_{i=1}^{z}\sum_{p|i}\mu(p)G(x,p)g(y,p)

然后跟 P4240 毒瘤之神的考验 差不多,将答案表示为关于 HH 的差分加下取整的形式。

再考虑根号分治,我们设一个阈值,将所有范围内的 HH 值递推预处理出来。

后面的再数论分块算。

#include <bits/stdc++.h>

using namespace std;

#define int long long

inline int read()
{
	int x = 0, f = 1;
	char c = getchar();
	while(c < '0' || c > '9')
	{
		if(c == '-') f = -1;
		c = getchar();
	}
	while(c >= '0' && c <= '9')
	{
		x = x * 10 + c - '0';
		c = getchar();
	}
	return x * f;
}

inline void write(int x)
{
	if(x < 0)
	{
		putchar('-');
		x = -x;
	}
	if(x > 9)
		write(x / 10);
	putchar(x % 10 + '0');
}

const int p = 23333;

const int _ = 5e4 + 7;

int T, n, m;

bool vis[_];

int cnt, pr[_], phi[_], mu[_];

const int B = 72;

vector<int> G[_], H[B + 10][B + 10], fac[_];

int calc(int x, int y, int z)
{
    int ans = 0;
    for (int o : fac[z])
        ans = (ans + mu[o] * G[o][x] % p * G[o][y]) % p + p;
    return ans % p;
}

void init()
{
	for (int i = 1; i <= _ - 7; i++)
    	for (int j = i; j <= _ - 7; j += i)
        	fac[j].push_back(i);
	phi[1] = mu[1] = 1;
	for(int i = 2; i <= _ - 7; ++i)
	{
		if(!vis[i])
		{
			pr[++cnt] = i;
			phi[i] = i - 1;
			mu[i] = -1;
		}
		for(int j = 1; j <= cnt && i * pr[j] <= _ - 7; ++j)
		{
			int p = i * pr[j];
			vis[p] = 1;
			if(i % pr[j] == 0)
			{
				phi[p] = phi[i] * pr[j];
				mu[p] = 0;
				break;
			}
			phi[p] = phi[i] * (pr[j] - 1);
			mu[p] = -mu[i];
		}
	}
	for (int i = 1; G[i].push_back(0), i <= _ - 7; ++i)
		for (int j = 1; j * i <= _ - 7; ++j)
			G[i].push_back((G[i][j - 1] + phi[i * j]) % p);
	for (int i = 1; i <= B; ++i)
		for (int j = 1; j <= B; ++j)
		{
			H[i][j].push_back(0);
			for (int k = 1; k <= (_ - 7) / max(i, j); ++k)
				H[i][j].push_back((H[i][j][k - 1] + calc(i, j, k)) % p);
		}
}

signed main()
{
	init();
	T = read();
	while(T--)
	{
		n = read(), m = read();
		if(n > m) swap(n, m);
		int ans = 0;
		for(int i = 1; i <= m / B; ++i)
			ans = (ans + calc(n / i, m / i, i)) % p;
		for(int l = m / B + 1, r; l <= n; l = r + 1)
		{
			r = min(n / (n / l), m / (m / l));
			ans = (ans + H[n / l][m / l][r] - H[n / l][m / l][l - 1] + p) % p;
		}
		write(ans % p);
		putchar('\n');
	}
	return 0;
}
posted @   蒟蒻orz  阅读(31)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示