https://blog.csdn.net/qq_34454069/article/details/81043195
【组合计数】
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define SF scanf #define PF printf #define MAXN 100010 using namespace std; int n; typedef long long ll; ll f[MAXN],num[MAXN]; int primes[MAXN],isprime[MAXN],tot; void prepare(){ f[1]=1; for(int i=2;i<=100000;i++){ if(isprime[i]==0){ primes[++tot]=i; f[i]=2; num[i]=1; } for(int j=1;j<=tot&&i*primes[j]<=100000;j++){ isprime[i*primes[j]]=1; if(i%primes[j]==0){ num[i*primes[j]]=num[i]+1; f[i*primes[j]]=f[i]/(num[i]+1ll)*(num[i*primes[j]]+1ll); break; } f[i*primes[j]]=f[i]*f[primes[j]]; num[i*primes[j]]=1; } } } int gcd(int x,int y){ if(y==0) return x; return gcd(y,x%y); } int main(){ prepare(); int t,a,b,c; SF("%d",&t); for(int i=1;i<=t;i++){ SF("%d%d%d",&a,&b,&c); //PF("{%lld %lld %lld} ",f[a],f[b],f[c]); //PF("{%d %d %d}",gcd(a,b),gcd(b,c),gcd(a,c)); int ab=gcd(a,b),bc=gcd(b,c),ac=gcd(a,c); ll ans1=f[a]*f[b]*f[c]; ll ans2=(f[ab]*f[ab]-f[ab])/2ll*f[c]; ll ans3=f[a]*(f[bc]*f[bc]-f[bc])/2ll; ll ans4=f[b]*(f[ac]*f[ac]-f[ac])/2ll; int td=gcd(gcd(a,c),b); ll ans5=(f[td]*f[td]-f[td])+f[td]*(f[td]-1ll)*(f[td]-2ll)/6ll*4ll; ll ans6=(f[ab]-f[td])*f[td]*(f[td]-1ll)/2ll; ll ans7=(f[bc]-f[td])*f[td]*(f[td]-1ll)/2ll; ll ans8=(f[ac]-f[td])*f[td]*(f[td]-1ll)/2ll; ll ans9=(f[ab]-f[td])*(f[bc]-f[td])*(f[ac]-f[td]); ll ans=ans1-ans2-ans3-ans4+ans5+ans6+ans7+ans8-ans9; /*if(ans==212) PF("[%d,%d,%d] ",a,b,c);*/ //PF("%lld %lld %lld %lld %lld",ans1,ans2,ans3,ans4,ans5); PF("%I64d ",ans); } }