Loading

CF1967B2(%你赛搬题题解)

。首先枚举 \(\gcd(a,b)=d\),令 \(A=\frac ad,B=\frac bd\)

\[Ad+Bd|Bd^2\\ A+B|Bd \]

此时 \(\gcd(A+B,B)=\gcd(A,B)=1\),所以

\[A+B|d \]

考虑 \(\mathcal O(n\ln n)\) 直接枚举 \(A+B=s\)

\[\sum_d \sum_{s|d} \sum_{A=1}^{\lfloor\frac nd\rfloor} \sum_{B=1}^{\lfloor\frac md\rfloor}[\gcd(A,B)=1][A+B=s] \]

然而后面没法 \(\mathcal O(1)\) 算。此时需要注意力。直觉上,本题的限制比 EZver 更严。实际上,有

\[A\le s\le d=\frac aA\\ A\le \sqrt a\le \sqrt n\\ \text{同理}\; B\le \sqrt m \]

那么暴力枚举有序对 \((A,B)\),可以 \(\mathcal O(1)\) 求出最大的满足条件的 \(d\),求 \(\sum \frac{d_{\max}}s\) 即可。复杂度 \(\mathcal O(\sqrt{nm})\)\(\mathcal O(n)\)

#include <cstdio>

int min(int a,int b){return a<b?a:b;}
int gcd(int a,int b){return !b?a:gcd(b,a%b);}

int main()
{
	int T;scanf("%d",&T);while(T--){
		int n,m,ans=0;scanf("%d%d",&n,&m);
		for(int a=1;a*a<=n;++a) for(int b=1;b*b<=m;++b)
			if(gcd(a,b)==1) ans+=min(n/a,m/b)/(a+b);
		printf("%d\n",ans);
	}
}
posted @ 2025-08-11 11:21  Albertvαn  阅读(70)  评论(0)    收藏  举报