BZOJ 2005: [Noi2010]能量采集(莫比乌斯反演)
2017-07-30 21:30
375 查看
http://www.lydsy.com/JudgeOnline/problem.php?id=2005
题意:
![](https://images2017.cnblogs.com/blog/1047463/201707/1047463-20170730211325005-1975348859.jpg)
思路:
首先要知道一点是,某个坐标(x,y)与(0,0)之间的整数点的个数为gcd(x,y),这样一来每个坐标损失的能量为2*gcd(x,y)-1。
所以在这道题目中要计算的就是
![](https://images2017.cnblogs.com/blog/1047463/201707/1047463-20170730212026443-1656762608.jpg)
f(d)表示gcd(x,y)=d的对数,那么F(d)表示d|gcd(x,y)的对数。
根据反演可以得到,
![](https://images2017.cnblogs.com/blog/1047463/201707/1047463-20170730212412427-55894731.jpg)
那么这道题的答案就是,
![](https://images2017.cnblogs.com/blog/1047463/201707/1047463-20170730212809537-485731421.jpg)
题意:
![](https://images2017.cnblogs.com/blog/1047463/201707/1047463-20170730211325005-1975348859.jpg)
思路:
首先要知道一点是,某个坐标(x,y)与(0,0)之间的整数点的个数为gcd(x,y),这样一来每个坐标损失的能量为2*gcd(x,y)-1。
所以在这道题目中要计算的就是
![](https://images2017.cnblogs.com/blog/1047463/201707/1047463-20170730212026443-1656762608.jpg)
f(d)表示gcd(x,y)=d的对数,那么F(d)表示d|gcd(x,y)的对数。
根据反演可以得到,
![](https://images2017.cnblogs.com/blog/1047463/201707/1047463-20170730212412427-55894731.jpg)
那么这道题的答案就是,
![](https://images2017.cnblogs.com/blog/1047463/201707/1047463-20170730212809537-485731421.jpg)
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<sstream> #include<vector> #include<stack> #include<queue> #include<cmath> #include<map> #include<set> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int INF = 0x3f3f3f3f; const int maxn = 100000 + 5; bool check[maxn]; int prime[maxn]; int mu[maxn]; ll sum[maxn]; void Mobius() { memset(check, false, sizeof(check)); mu[1] = 1; int tot = 0; for (int i = 2; i <= maxn; i++) { if (!check[i]) { prime[tot++] = i; mu[i] = -1; } for (int j = 0; j < tot; j++) { if (i * prime[j] > maxn) { break; } check[i * prime[j]] = true; if (i % prime[j] == 0) { mu[i * prime[j]] = 0; break; } else { mu[i * prime[j]] = -mu[i]; } } } sum[0]=0; for(int i=1;i<maxn;i++) sum[i]=sum[i-1]+mu[i]; return ; } ll solve(int n, int m) { if(n>m) swap(n,m); ll tmp=0; for(int i=1,last=0;i<=n;i=last+1) { last=min(n/(n/i),m/(m/i)); tmp+=(sum[last]-sum[i-1])*(n/i)*(m/i); } return tmp; } int n, m; int main() { //freopen("in.txt","r",stdin); Mobius(); while(~scanf("%d%d",&m,&n)) { ll ans=0; for(int i=1;i<=min(n,m);i++) //枚举d ans+=solve(n/i,m/i)*i; //这儿求gcd(x,y)=d的对数,但是如果/i的话就相当于计算gcd(x,y)=1的对数 //简化了计算 printf("%lld\n",2*ans-(ll)n*m); } return 0; }
相关文章推荐
- BZOJ 2005 [Noi2010]能量采集 (数学+容斥 或 莫比乌斯反演)
- BZOJ 2005: [Noi2010]能量采集(莫比乌斯反演)
- [BZOJ2005][NOI2010]能量采集(莫比乌斯反演)
- Bzoj 2005: [Noi2010]能量采集(莫比乌斯反演)
- [BZOJ2005][NOI2010]能量采集(莫比乌斯反演)
- BZOJ 2005 NOI2010 能量采集 莫比乌斯反演
- _bzoj2005 [Noi2010]能量采集
- bzoj 2005 NOI 2010 能量采集
- bzoj2005[Noi2010]能量采集
- [bzoj2005][Noi2010][能量采集] (容斥 or 欧拉函数)
- BZOJ 2005: [Noi2010]能量采集|容斥原理
- 【NOI2010】【BZOJ2005】能量采集(莫比乌斯反演、乱搞)
- bzoj 2005: [Noi2010]能量采集
- BZOJ 2005 [Noi2010]能量采集
- 【BZOJ】2005 [Noi2010]能量采集
- BZOJ 2005: [Noi2010]能量采集( 数论 + 容斥原理 )
- 【NOI 2010】【BZOJ 2005】【JZOJ 2225】能量采集
- bzoj2005 [Noi2010]能量采集
- bzoj 2005: [Noi2010]能量采集
- [BZOJ2005][NOI2010]能量采集