好题推荐——另类最小公倍数(gcd)
题面
题解
想到将最大公约数提出来,变为 gcd(a,b)∣a,x−b,y∣gcd(a,b)|a^,x-b^,y|gcd(a,b)∣a,x−b,y∣,答案即转化为枚举 d=gcd(a,b)d=gcd(a,b)d=gcd(a,b),求有多少个无序数对 (a,,b,)(a^,,b^,)(a,,b,) ,满足 gcd(a,,b,)=1gcd(a^,,b^,)=1gcd(a,,b,)=1 且 a,b,≤⌊ld⌋a^,b^,\le \left \lfloor \frac{l}{d} \right \rfloora,b,≤⌊dl⌋ 。显然想到枚举所有 a,a^,a,和b,b^,b,的组合,求前缀和即可,时间复杂度 O(n(logn)2)O(n(logn)^2)O(n(logn)2)
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
long long l,xx,yy;
long long t[N],s[N];
int main()
{freopen("lcm.in","r",stdin);freopen("lcm.out","w",stdout);cin>>l>>xx>>yy;for(long long i=1;i<=l;i++){for(long long j=i;j*i<=l;j++){if(__gcd(j,i)!=1) continue ;if(i!=j) t[i*j]+=abs(i*xx-j*yy)+abs(j*xx-i*yy);else t[i*j]+=abs(i*xx-j*yy);}}for(int i=1;i<=l;i++)s[i]=s[i-1]+t[i];long long ans=0;for(long long i=1;i<=l;i++){ans+=s[l/i]*i;}cout<<ans;return 0;
}