Http://www.lydsy.com/JudgeOnline/problem.php?id=1101
Given a,b,d, how many gcd (x, y) ==d (1<=x<=a&&1<=y<=b) are asked
Ideas:
ΣGCD (x, y) ==d (1<=x<=a,1<=y<=b)
=
ΣGCD (x, y) ==1 (1<=x<=a/d,1<=y<=b/d)
Make g (i) =num (I|GCD (x, y)) =n/i*m/i
G (i) =num (I=GCD (x, y))
G (i) =σg (d) *u (d/i) (i|d)
The answer is G (1)
G (1) =σg (i) *u (i) (1<=i<=min (n,m))
=σ (n/i) * (m/i) *u (i)
So make a prefix of U (i) and so that you can work together n/i and m/i the same I
1#include <algorithm>2#include <cstdio>3#include <cmath>4#include <cstring>5#include <iostream>6 intmul[200005],mark[200005],sum[200005],p[200005];7 intRead () {8 CharCh=getchar ();intt=0, f=1;9 while(ch<'0'|| Ch>'9'){if(ch=='-') f=-1; ch=GetChar ();}Ten while('0'<=ch&&ch<='9') {t=t*Ten+ch-'0'; ch=GetChar ();} One returnt*F; A } - voidinit () { -mul[1]=1; the for(intI=2; i<=50000; i++){ - if(!Mark[i]) { -p[++p[0]]=i; -mul[i]=-1; + } - for(intj=1; j<=p[0]&&i*p[j]<=50000; j + +){ +mark[p[j]*i]=1; A if(I%p[j]) mul[p[j]*i]=mul[i]* (-1); at Else { -mul[p[j]*i]=0; - Break; - } - } - } insum[0]=0; - for(intI=1; i<=50000; i++) tosum[i]=sum[i-1]+Mul[i]; + } - intCalintAintb) { the if(a>b) Std::swap (a); * intres=0, n=a,m=b; $ for(intI=1, j;i<=a;i=j+1){Panax NotoginsengJ=std::min (n/(n/i), m/(m/i)); -res+= (a/i) * (b/i) * (sum[j]-sum[i-1]); the } + returnRes; A } the intMain () { + intq=read (); - init (); $ while(q--){ $ intA=read (), B=read (), d=read (); -printf"%d\n", Cal (a/d,b/d)); - } the}
Bzoj 1101 Zap (Möbius inversion)