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 }

 

posted @ 2017-04-12 21:39  ws_ccd  阅读(180)  评论(0编辑  收藏  举报