[NOI2010] 能量采集
2018-03-26 08:56
218 查看
题目描述:
emmmm.题目分析:
看一下不难发现 每个位置的损失值其实就是 gcd(i,j)∗2−1gcd(i,j)∗2−1N2N2暴力枚举就有80分了
转化一下即求
∑min(n,m)d=1[(2∗d−1)∗∑(gcd(i,j))=d]∑d=1min(n,m)[(2∗d−1)∗∑(gcd(i,j))=d]
求gcd(i,j)=dgcd(i,j)=d用莫比乌斯反演即可
总的复杂度即O(n(√n))O(n(n))
卡一卡就过去了
正解好像是容斥,而且代码巨短~
题目链接:
BZOJ 2005Luogu 1447
Ac 代码:
#include <iostream> #include <cstdio> #include <cstring> #define int long long const int maxm=110000; int mu[maxm],prime[maxm],sum[maxm],cnt,n,m; bool vis[maxm]; void getmu() { mu[1]=1,vis[1]=1; for(int i=2;i<=maxm;i++) { if(!vis[i]) { prime[++cnt]=i; //printf("%d\n",i); mu[i]=-1; } for(int j=1;j<=cnt&&prime[j]*i<=maxm;j++) { vis[prime[j]*i]=1; if(i%prime[j]==0) { mu[prime[j]*i]=0; break; } mu[prime[j]*i]=-mu[i]; } } for(int i=1;i<=maxm;i++) sum[i]=mu[i]+sum[i-1]; } int gcd(int x,int y) { int ans=0,last; for(int i=1;i<=std::min(x,y);i=last+1) { last=std::min(x/(x/i),y/(y/i)); ans+=(sum[last]-sum[i-1])*(x/i)*(y/i); } return ans; } int cal(int a,int b,int c,int d,int k) { a--,c--; a/=k,b/=k,c/=k,d/=k; return gcd(b,d)-gcd(b,c)-gcd(a,d)+gcd(a,c); } main() { getmu(); //printf("Yes\n"); scanf("%lld%lld",&n,&m); int ans=0; for(int i=1;i<=std::min(n,m);i++) ans+=(cal(1,n,1,m,i)*(2*i-1)); printf("%lld\n",ans); return 0; }
相关文章推荐
- [bzoj2005][Noi2010]能量采集
- [bzoj 2005][NOI 2010]能量采集(容斥原理+递推)
- bzoj 2005: [Noi2010]能量采集
- [Noi2010] D1T1 能量采集 (欧拉函数)
- bzoj2005: [Noi2010]能量采集
- [NOI2010]能量采集(数论+递推)
- bzoj 2005: [Noi2010] 能量采集
- 洛谷P1447 - [NOI2010]能量采集
- bzoj2005【NOI2010】能量采集
- Bzoj2005[Noi2010]能量采集
- 相同最小公约数的计算——[NOI2010]能量采集
- BZOJ 2005: [Noi2010]能量采集(莫比乌斯反演)
- BZOJ 2005: [Noi2010]能量采集|容斥原理
- bzoj2005 [Noi2010]能量采集
- 2005: [Noi2010]能量采集
- BZOJ2005 [Noi2010]能量采集
- 【BZOJ2005】【NOI2010】能量采集(莫比乌斯反演,容斥原理)
- 2005: [Noi2010]能量采集
- NOI2010 能量采集
- [bzoj 2005] [NOI2010]能量采集