51nod1222最小公倍数计数
http://210.33.19.103/contest/1113/problem/2
同学的神仙做法:
首先考虑先去掉X<=Y的限制,也就是先计算满足要求的任意有序pair(X,Y)的数量,再用一些简单操作(略去)得到目标答案
化简式子可以得到$\sum_{d}\mu(d)\sum_a\sum_b\sum_c[abc<={\lfloor}\frac{n}{d^2}{\rfloor}]$
可以强行给a,b,c规定一个顺序。设a是最小的,则a只需要枚举到$(\frac{n}{d^2})^{1/3}$就行
剩下有很多做法了,略去了
1 %:pragma GCC optimize(2) 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<vector> 6 #include<cmath> 7 using namespace std; 8 #define fi first 9 #define se second 10 #define mp make_pair 11 #define pb push_back 12 typedef long long ll; 13 typedef unsigned long long ull; 14 int mu[400001]; 15 int prime[100011],len; 16 bool nprime[400001]; 17 /* 18 ll calc0(ll n) 19 { 20 ll d,i,j,k,tan1,tan2,tan3,t1; 21 for(d=1;;++d) 22 { 23 if(d*d>n) break; 24 t1=n/(d*d); 25 tan1=tan2=tan3=0; 26 for(i=1;i<=100;++i) 27 for(j=1;j<=100;++j) 28 for(k=1;k<=100;++k) 29 if(i*j*k<=t1) 30 if(i==j&&j==k) 31 ++tan3; 32 else if(i==j||j==k||i==k) 33 ++tan2; 34 else ++tan1; 35 printf("at%lld %lld %lld\n",tan1,tan2,tan3); 36 } 37 return 233; 38 } 39 */ 40 ll calc(ll n) 41 { 42 ll d,t1,t2,endj,i,j,j1,tan1,tan2,tan3,ans=0,endi; 43 for(d=1;;++d) 44 if(mu[d]) 45 { 46 if(d*d>n) break; 47 t1=n/(d*d); 48 tan1=tan2=tan3=0; 49 for(i=1;;++i) 50 { 51 if(i*i*i>t1) break; 52 t2=t1/i; 53 endj=ll(sqrt(t2+0.5)); 54 for(j=i+1;j<=endj;j=j1+1) 55 { 56 j1=min(endj,t2/(t2/j)); 57 tan1+=(t2/j)*(j1-j+1); 58 } 59 if(i+1<=endj) 60 tan1-=(endj+i+1)*(endj-i)/2; 61 } 62 tan1*=6; 63 endi=ll(sqrt(t1+0.5)); 64 for(i=1;i<=endi;++i) 65 tan2+=t1/(i*i); 66 for(i=1;;++i) 67 { 68 if(i*i*i>t1) break; 69 ++tan3; 70 } 71 tan2=(tan2-tan3)*3; 72 ans+=mu[d]*(tan1+tan2+tan3); 73 //printf("1t%lld %lld %lld %lld\n",d,tan1,tan2,tan3); 74 } 75 return ans; 76 } 77 int main() 78 { 79 ll i,j,t; 80 mu[1]=1; 81 for(i=2;i<=400000;i++) 82 { 83 if(!nprime[i]) prime[++len]=i,mu[i]=-1; 84 for(j=1;j<=len&&(t=i*prime[j])<=400000;j++) 85 { 86 nprime[t]=1; 87 if(i%prime[j]==0) {mu[t]=0;break;} 88 else mu[t]=-mu[i]; 89 } 90 } 91 ll a,b; 92 scanf("%lld%lld",&a,&b); 93 printf("%lld\n",(calc(b)-calc(a-1)+b-a+1)/2); 94 //calc0(b);calc0(a-1); 95 return 0; 96 }