【51nod】1222 最小公倍数计数 莫比乌斯反演+组合计数
2018-03-01 21:19
375 查看
【题意】给定a和b,求满足a<=lcm(x,y)<=b && x<y的数对(x,y)个数。a,b<=10^11。
【算法】莫比乌斯反演+组合计数
【题解】★具体推导过程参考:51nod1222 最小公倍数计数
过程运用到的技巧:
1.将所有i和j的已知因子提取出来压缩上届。
2.将带有μ(k)的k提到最前面,从而后面变成单纯的三元组形式。
最终形式:
$$ans=\sum_{k=1}^{\sqrt n} \mu(k) \sum_{d} \sum_{i} \sum_{j} [i*j*d<=\frac{n}{k^2}]$$
问题转化为枚举(d,i,j)三元组满足其乘积<=n/k^2。
虽然题目要求组合(有序),但是有d的存在,所以先求排列(无序)。
但是三元组的排列不方便统计,所以求三元组的组合乘上排列系数
先算严格从小到大的,然后减去两个相同的和三个相同的。
最后+n后/2就变成组合。
听说复杂度O(n^(2/3))。
#include<cstdio> #include<cmath> #define int long long using namespace std; const int maxn=1000010; int miu[maxn],prime[maxn],tot; bool vis[maxn]; int solve(int x){ if(!x)return 0; int N=(int)sqrt(x)+1,ans=0; for(int k=1;k<=N;k++)if(miu[k]){ int n=x/(k*k); for(int d=1;d*d*d<=n;d++){ for(int i=d+1;i*i*d<=n;i++)ans+=miu[k]*((n/(d*i)-i)*6+3); ans+=miu[k]*((n/(d*d)-d)*3+1); } } return (ans+x)/2; } #undef int int main(){ #define int long long int A,B; scanf("%lld%lld",&A,&B); int N=(int)sqrt(B)+1; miu[1]=1; for(int i=2;i<=N;i++){ if(!vis[i]){miu[prime[++tot]=i]=-1;} for(int j=1;j<=tot&&i*prime[j]<=N;j++){ vis[i*prime[j]]=1;// if(i%prime[j]==0)break; miu[i*prime[j]]=-miu[i]; } } printf("%lld\n",solve(B)-solve(A-1)); return 0; }View Code
相关文章推荐
- [数论][莫比乌斯反演] 51Nod 1222 最小公倍数计数
- 51nod 1222 最小公倍数计数
- 51nod 1222 最小公倍数计数【莫比乌斯反演】
- 【51NOD 1222】最小公倍数计数
- 51nod 1222 最小公倍数计数
- 【51Nod 1222】最小公倍数计数
- [莫比乌斯反演 复杂度分析] 51Nod 1222 最小公倍数计数
- 51nod-1222-最小公倍数计数
- 51nod 1222 最小公倍数计数 莫比乌斯反演+杜教筛
- [51nod 1222]最小公倍数计数
- 51 nod 1222 最小公倍数计数
- 51NOD 1222 最小公倍数计数 [莫比乌斯反演 杜教筛]
- 51nod1222 最小公倍数计数
- 51nod 1190 最小公倍数之和 V2【莫比乌斯反演】
- 51nod 1601 完全图的最小生成树计数 Trie+kruskal
- 51Nod->1419最小公倍数挑战 (数论)
- 最小公倍数LCM 51Nod - 1012
- 【51nod1222】【最小公倍数计数】【莫比乌斯反演】
- [反演 数论] 51Nod 1355 斐波那契的最小公倍数
- 51nod 1601 完全图的最小生成树计数 字典树+最小生成树