Description
Seek Sigma gcd (x, y) *2-1,1<=x<=n, 1<=y<=m. N, M<=1e5.
Solution
F (n) is the number of GCD exactly n (x, y)
F (n) is gcd is the number of multiples of n (x, y)
What we're asking for is F (i)
However, this is not a direct calculation, but f (i) can be directly used (n/i) * (m/i) to get
So there's f (n) =sigma n|i f (i)
So there is F (n) =sigma n|i mu (i) *f (i)
This is the Möbius inversion, but the problem is that it is easy to get the same formula directly with the idea of the repulsion.
So consider every GCD contribution.
Dividing N and m by GCD is equivalent to requiring n times f (1)
Logn each time
Code
There is no need to reverse the practice, probably from the back to the calculation, each step is strictly defined, with the capacity to do.
This problem is I do bzoj the third question, but then only 80/90 violence then to see the problem of the allowance, at that time felt that each GCD separate consideration contribution is magical, but for now is again natural but the idea.
1#include <cstdio>2#include <algorithm>3#include <cstring>4 #definell Long Long5 using namespacestd;6 Const intmaxn=1e5+5;7 8 intflag[maxn],prime[maxn],cnt;9 intMU[MAXN];Ten intn,m; One A intGETMU () { -mu[1]=1; - for(intI=2; i<=n;i++){ the if(!Flag[i]) { -mu[i]=-1; -prime[++cnt]=i; - } + for(intj=1; i*prime[j]<=n&&j<=cnt;j++){ -flag[i*prime[j]]=1; + if(i%prime[j]==0){ Amu[i*prime[j]]=0; at Break; - } -mu[i*prime[j]]=-Mu[i]; - } - } - } in -ll work (intx) { toll ret=0; + intn=n/x,m=m/x; - for(intI=1; i<=n;i++) theret+=1ll*mu[i]* (n/i) * (m/i); * returnret; $ }Panax Notoginseng - intMain () { thescanf"%d%d",&n,&M); + if(n>M) Swap (n,m); A GETMU (); the +ll ans=0; - for(intI=1; i<=n;i++) $Ans+=work (i) * (2*i-1); $printf"%lld\n", ans); - return 0; -}
"BZOJ2005 inversion" [NOI2010] energy harvesting