51nod 1222 最小公倍数计数
求:Σ(i<=r)Σ(j<=r)lcm(i,j)[i<=j]-Σ(i<l)Σ(j<l)lcm(i,j)[i<=j] == Ans
然后搞一搞 Σ(i<=n)Σ(j<=n) (i*j/gcd(i,j))[i<=j] == Σ(d<=n)Σ(i<=n/d)Σ(j<=n/d)(i*j*d<=n) [i<=j] [gcd(i,j)==1]
反演一下,,不想写公式,,
然后开心的扒题解2333
%%% http://blog.csdn.net/worldwide_d/article/details/54584716
这个题应该是假的杜教筛
1 #include<bits/stdc++.h> 2 #define LL long long 3 using namespace std; 4 5 const int maxn=1e6+5; 6 7 int prime[maxn],mo[maxn]; 8 bool vis[maxn]; 9 10 LL ans,l,r; 11 12 void mobius() 13 { 14 int L=sqrt(100000000000LL)+1; mo[1]=1; 15 for (int i=2; i<=L; i++) 16 { 17 if (!vis[i]) mo[i]=-1,prime[++prime[0]]=i; 18 for (int j=1; j<=prime[0] && i*prime[j]<=L; j++) 19 { 20 vis[i*prime[j]]=1; 21 if (i%prime[j]) mo[i*prime[j]]=-mo[i]; 22 else{mo[i*prime[j]]=0; break;} 23 } 24 } 25 } 26 27 LL solve(LL n) 28 { 29 if (!n) return 0; ans=0; 30 for (int k=1; (LL)k*k<=n; k++) 31 { 32 if (!mo[k]) continue; 33 LL m=n/((LL)k*k),s=0; 34 for (int i=1; (LL)i*i*i<=m; i++) 35 { 36 for (int j=i+1; (LL)i*j*j<=m; j++) 37 s+=(m/((LL)i*j)-j)*6+3; // *6是3个数都不同,方案数是3!,+3是两个j相同的方案数 38 s+=(m/((LL)i*i)-i)*3+1; // 下面*3是2个i相同的方案,+1是3个数都是i 39 } 40 ans+=(LL)mo[k]*s; 41 } 42 return (ans+n)/2; 43 } 44 45 int main() 46 { 47 mobius(); 48 scanf("%lld%lld",&l,&r); 49 printf("%lld\n",solve(r)-solve(l-1)); 50 return 0; 51 }