码迷,mamicode.com
首页 > 其他好文 > 详细

【莫比乌斯反演】【线性筛】bzoj2005 [Noi2010]能量采集

时间:2017-09-08 00:21:42      阅读:187      评论:0      收藏:0      [点我收藏+]

标签:noi2010   bre   zoj   blog   采集   logs   [1]   noi   wap   

http://blog.csdn.net/Clove_unique/article/details/51089272

Key:1、连接平面上某个整点(a,b)到原点的线段上有gcd(a,b)个整点。

2、欧拉函数的性质之一:若(N%a==0 && (N/a)%a==0) 则有:phi(N)=phi(N/a)*a。由此可以线性筛。

3、一个数的所有因子的phi值之和恰好等于这个数本身。

#include<cstdio>
#include<algorithm>
using namespace std;
#define N 100000
typedef long long ll;
bool notpri[N+5];
int pri[N+5];
ll phi[N+5];
void shai_eular()//线性筛欧拉函数,顺便处理前缀和
{
	notpri[1]=1;
	phi[1]=1;
	for(int i=2;i<=N;++i){
		if(!notpri[i]){
			pri[++pri[0]]=i;
			phi[i]=(ll)(i-1);
		}
        for(int j=1;j<=pri[0] && (ll)i*(ll)pri[j]<=(ll)N;++j){
			notpri[i*pri[j]]=1;
			if(i%pri[j]==0){
				phi[i*pri[j]]=phi[i]*(ll)pri[j];
				break;
			}
			phi[i*pri[j]]=phi[i]*(ll)(pri[j]-1);
		}
	}
	for(int i=2;i<=N;++i){
		phi[i]+=phi[i-1];
	}
}
int n,m;
int main(){
	shai_eular();
	scanf("%d%d",&n,&m);
	if(n>m){
		swap(n,m);
	}
	ll ans=0;
	for(int i=1;i<=n;){
		int j1=n/(n/i);
		int j2=m/(m/i);
		int j=min(j1,j2);
		ans+=(phi[j]-phi[i-1])*(n/i)*(m/i);
		i=j+1;
	}
	printf("%lld\n",2ll*ans-(ll)n*(ll)m);
	return 0;
}

【莫比乌斯反演】【线性筛】bzoj2005 [Noi2010]能量采集

标签:noi2010   bre   zoj   blog   采集   logs   [1]   noi   wap   

原文地址:http://www.cnblogs.com/autsky-jadek/p/7492381.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!